first attempt at networking (does not work)
This commit is contained in:
parent
a134513b9c
commit
c85581749b
@ -31,6 +31,6 @@ meson build server # for server only
|
|||||||
|
|
||||||
## Running
|
## Running
|
||||||
```shell
|
```shell
|
||||||
./build/client
|
./build/client # for client application
|
||||||
./build/server
|
./build/server # for server application
|
||||||
```
|
```
|
40
client.cpp
40
client.cpp
@ -1,10 +1,46 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <opencv2/videoio.hpp>
|
#include <opencv2/videoio.hpp>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <packets/ImagePacket.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
cv::VideoCapture cap = cv::VideoCapture(0);
|
cv::VideoCapture cap = cv::VideoCapture(0);
|
||||||
cout << "Hello World!" << endl;
|
|
||||||
|
int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
// specifying address
|
||||||
|
sockaddr_in serverAddress;
|
||||||
|
serverAddress.sin_family = AF_INET;
|
||||||
|
serverAddress.sin_port = htons(8080);
|
||||||
|
serverAddress.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
cv::Mat image = cv::Mat::zeros(cv::Size(640, 480), CV_8UC3);
|
||||||
|
ImagePacket packet = ImagePacket(&image, 0);
|
||||||
|
|
||||||
|
// sending connection request
|
||||||
|
connect(clientSocket, (struct sockaddr*)&serverAddress,
|
||||||
|
sizeof(serverAddress));
|
||||||
|
|
||||||
|
unsigned long pos = 0;
|
||||||
|
unsigned long len = image.total() * image.elemSize();
|
||||||
|
char buffer[IMAGEPACKET_SIZE];
|
||||||
|
|
||||||
|
cout << "Image length " << len << endl;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
cap.read(image);
|
||||||
|
packet = ImagePacket(&image, pos);
|
||||||
|
packet.serialize(buffer);
|
||||||
|
send(clientSocket, buffer, sizeof(buffer), 0);
|
||||||
|
cout << "Sent packet with index " << pos << endl;
|
||||||
|
pos = (pos + SLICE_SIZE) % len;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(clientSocket);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -1,38 +1,56 @@
|
|||||||
#include "ImagePacket.h"
|
#include "ImagePacket.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Construct a packet from an OpenCV Mat, and a beginning index. It will take PACKET_SIZE bytes from the start and add
|
|
||||||
* it to its slice
|
|
||||||
*/
|
|
||||||
ImagePacket::ImagePacket(const cv::Mat *image, const int begin) {
|
|
||||||
const uchar *target = &image->data[begin];
|
|
||||||
// TODO: handle out of index cases, pad with zeroes. probably also instantiate our byte array with zeroes
|
|
||||||
for (int i = 0; i < PACKET_SIZE; i++) {
|
|
||||||
slice[i] = target[begin + i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct a packet from a raw array of unsigned chars, and a beginning index. It will take PACKET_SIZE bytes from the
|
* Construct a packet from a raw array of unsigned chars, and a beginning index. It will take PACKET_SIZE bytes from the
|
||||||
* start and add it to its slice. This will be more useful for embedded scenarios where OpenCV will likely not be used.
|
* start and add it to its slice. This will be more useful for embedded scenarios where OpenCV will likely not be used.
|
||||||
*/
|
*/
|
||||||
ImagePacket::ImagePacket(const uchar *image, const int begin) {
|
ImagePacket::ImagePacket(const uchar *image, const int begin) {
|
||||||
|
this->begin = begin;
|
||||||
|
this->slice = new uchar[SLICE_SIZE];
|
||||||
const uchar *target = &image[begin];
|
const uchar *target = &image[begin];
|
||||||
// TODO: handle out of index cases, pad with zeroes. probably also instantiate our byte array with zeroes
|
// TODO: handle out of index cases, pad with zeroes. probably also instantiate our byte array with zeroes
|
||||||
for (int i = 0; i < PACKET_SIZE; i++) {
|
for (int i = 0; i < SLICE_SIZE; i++) {
|
||||||
slice[i] = target[begin + i];
|
this->slice[i] = target[begin + i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* destructor frees memory
|
||||||
|
*/
|
||||||
|
ImagePacket::~ImagePacket() = default;
|
||||||
|
|
||||||
|
unsigned long ImagePacket::getBegin() const {
|
||||||
|
return this->begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Apply the packet to an OpenCV Mat.
|
* Apply the packet to an OpenCV Mat.
|
||||||
*/
|
*/
|
||||||
int ImagePacket::apply(const cv::Mat *image) const {
|
int ImagePacket::apply(const cv::Mat *image) const {
|
||||||
uchar *target = &image->data[begin];
|
uchar *target = &image->data[this->begin];
|
||||||
// TODO: handle out of index cases
|
// TODO: handle out of index cases
|
||||||
for (int i = 0; i < PACKET_SIZE; i++) {
|
for (int i = 0; i < SLICE_SIZE; i++) {
|
||||||
target[begin + i] = slice[i];
|
target[this->begin + i] = this->slice[i];
|
||||||
}
|
}
|
||||||
// TODO: return the actual written size of the packet
|
// TODO: return the actual written size of the packet
|
||||||
return PACKET_SIZE;
|
return SLICE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serialize the object into a byte array
|
||||||
|
*/
|
||||||
|
void ImagePacket::serialize(char* buffer) const {
|
||||||
|
// TODO: keep the endianness consistent between systems
|
||||||
|
std::memcpy(buffer, &this->begin, sizeof(this->begin));
|
||||||
|
std::memcpy(buffer + sizeof(this->begin), &this->slice, SLICE_SIZE * sizeof(uchar));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deserialize the object from a byte array
|
||||||
|
*/
|
||||||
|
void ImagePacket::deserialize(char* buffer) {
|
||||||
|
// TODO: keep the endianness consistent between systems
|
||||||
|
std::memcpy(&this->begin, buffer, sizeof(this->begin));
|
||||||
|
std::memcpy(this->slice, buffer + sizeof(this->begin), SLICE_SIZE * sizeof(uchar));
|
||||||
|
}
|
@ -2,17 +2,23 @@
|
|||||||
#define IMAGEPACKET_H
|
#define IMAGEPACKET_H
|
||||||
#include <opencv2/core/mat.hpp>
|
#include <opencv2/core/mat.hpp>
|
||||||
|
|
||||||
#define PACKET_SIZE 768
|
#define SLICE_SIZE 768
|
||||||
|
#define IMAGEPACKET_SIZE sizeof(int) + (SLICE_SIZE * sizeof(uchar))
|
||||||
|
|
||||||
class ImagePacket {
|
class ImagePacket {
|
||||||
public:
|
public:
|
||||||
ImagePacket(const cv::Mat *image, int begin);
|
ImagePacket(const cv::Mat *image, int begin) : ImagePacket(image->data, begin) {}
|
||||||
ImagePacket(const uchar *image, int begin);
|
ImagePacket(const uchar *image, int begin);
|
||||||
|
~ImagePacket();
|
||||||
|
|
||||||
|
unsigned long getBegin() const;
|
||||||
int apply(const cv::Mat *image) const;
|
int apply(const cv::Mat *image) const;
|
||||||
|
|
||||||
|
void serialize(char* buffer) const;
|
||||||
|
void deserialize(char* buffer);
|
||||||
private:
|
private:
|
||||||
int begin;
|
unsigned long begin;
|
||||||
uchar slice[PACKET_SIZE];
|
uchar *slice;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //IMAGEPACKET_H
|
#endif //IMAGEPACKET_H
|
||||||
|
45
server.cpp
45
server.cpp
@ -1,20 +1,55 @@
|
|||||||
#include <opencv2/highgui.hpp>
|
#include <opencv2/highgui.hpp>
|
||||||
#include <opencv2/videoio.hpp>
|
|
||||||
#include <opencv2/core/mat.hpp>
|
#include <opencv2/core/mat.hpp>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <packets/ImagePacket.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// TODO: read image data from socket instead of VideoCapture
|
// TODO: read image data from socket instead of VideoCapture
|
||||||
cv::VideoCapture cap = cv::VideoCapture(0);
|
// creating socket
|
||||||
bool running = true;
|
int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
// specifying the address
|
||||||
|
sockaddr_in serverAddress;
|
||||||
|
serverAddress.sin_family = AF_INET;
|
||||||
|
serverAddress.sin_port = htons(8080);
|
||||||
|
serverAddress.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
// binding socket.
|
||||||
|
bind(serverSocket, (struct sockaddr*)&serverAddress,
|
||||||
|
sizeof(serverAddress));
|
||||||
|
|
||||||
|
// listening to the assigned socket
|
||||||
|
listen(serverSocket, 5);
|
||||||
|
|
||||||
|
// accepting connection request
|
||||||
|
int clientSocket
|
||||||
|
= accept(serverSocket, nullptr, nullptr);
|
||||||
|
|
||||||
// TODO: handle multiple images
|
// TODO: handle multiple images
|
||||||
cv::Mat image = cv::Mat::zeros(480, 640, CV_8UC3);
|
cv::Mat image = cv::Mat::zeros(480, 640, CV_8UC3);
|
||||||
|
|
||||||
|
// setup packet buffer
|
||||||
|
char buffer[IMAGEPACKET_SIZE] = { 0 };
|
||||||
|
ImagePacket packet = ImagePacket(&image, 0);
|
||||||
|
|
||||||
|
bool running = true;
|
||||||
// TODO: make this asynchronous. probably do that in tandem with setting up networking
|
// TODO: make this asynchronous. probably do that in tandem with setting up networking
|
||||||
while (running) {
|
while (running) {
|
||||||
cap.read(image);
|
// receive data
|
||||||
|
recv(clientSocket, buffer, sizeof(buffer), 0);
|
||||||
|
packet.deserialize(buffer);
|
||||||
|
cout << "received packet with index " << packet.getBegin() << endl;
|
||||||
|
packet.apply(&image);
|
||||||
|
|
||||||
imshow("image", image);
|
imshow("image", image);
|
||||||
running = cv::waitKey(30) != 27;
|
running = cv::waitKey(30) != 27;
|
||||||
}
|
}
|
||||||
|
close(serverSocket);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user