项目源码: socket_opencv
服务端
1.SocketMatTransmissionServer.h:
#ifndef __SOCKETMATTRANSMISSIONSEVER_H__
#define __SOCKETMATTRANSMISSIONSEVER_H__
#include "opencv2/opencv.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace cv;
#define PACKAGE_NUM 1
#define IMG_WIDTH 640
#define IMG_HEIGHT 480
#define BLOCKSIZE IMG_WIDTH*IMG_HEIGHT*3/PACKAGE_NUM
struct recvBuf
{
char head[2];
char buf[BLOCKSIZE];
//int flag;
};
struct sentBuf
{
char head[2];
char buf[BLOCKSIZE];
//int flag;
};
class SocketMatTransmissionServer
{
public:
SocketMatTransmissionServer(void);
~SocketMatTransmissionServer(void);
int sockConn;
int server_sockfd;
private:
struct recvBuf data;
struct sentBuf data_s;
int needRecv;
int count;
public:
int socketInit(int PORT);
int socketConnect(void);
int transmit(cv::Mat image);
int receive(cv::Mat& image);
void socketDisconnect(void);
};
#endif
这里定义了两个结构体类型:
struct recvBuf
{
char head[2];
char buf[BLOCKSIZE];
//int flag;
};
struct sentBuf
{
char head[2];
char buf[BLOCKSIZE];
//int flag;
};
这里定义了类SocketMatTransmissionServer
2.SocketMatTransmissionServer.cpp:
类的构造函数和析构函数都是私有数据成员:
SocketMatTransmissionServer::SocketMatTransmissionServer(void)
{
}
SocketMatTransmissionServer::~SocketMatTransmissionServer(void)
{
}
公共成员函数SocketMatTransmissionServer::socketInit(int PORT)
int SocketMatTransmissionServer::socketInit(int PORT)
{
server_sockfd = socket(AF_INET,SOCK_STREAM, 0); // 建立套接字
struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
int contain=1;
setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &contain, sizeof(int));
// 为套接字设置选项
if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
{
perror("bind");
return -1;
}
if(listen(server_sockfd,5) == -1)
{
perror("listen");
return -1;
}
}
3.Server.cpp:
代码:
#include "SocketMatTransmissionServer.h"
int main()
{
SocketMatTransmissionServer socketMat;
if (socketMat.socketInit(6666) < 0)
{
return 0;
}
cv::Mat img_r;
int key = -1;
int n = -1;
while(1)
{
if (socketMat.socketConnect() < 0)
{
continue;
}
while (1)
{
n = socketMat.receive(img_r);
if(n > 0)
{
printf("Server recv!\n");
socketMat.transmit(img_r);
//cv::imshow("Server",img_r);
//key = cv::waitKey(1);
//if (key == 'q')
// break;
}
else
{
printf("Server recv error!\n");
break;
}
//printf("Server !!!!!\n");
//socketMat.transmit(img_r);
}
//socketMat.socketDisconnect();
}
socketMat.socketDisconnect();
return 0;
}
4.重点关注SocketMatTransmissionServer.cpp中的receive(cv::Mat& image):
int SocketMatTransmissionServer::receive(cv::Mat& image)
{
int returnflag = 0;
cv::Mat img(IMG_HEIGHT, IMG_WIDTH, CV_8UC3, cv::Scalar(0));
needRecv = sizeof(recvBuf) - 2;
// sizeof(recvBuf) = 921602
count = 0;
memset(&data,0,sizeof(data)); // sizeof(data) = 921602
int pos = 0;
int len0 = 0;
// sockConn是客户端的套接字描述符
recv(sockConn, (char*)(&data), 2, 0);
printf("===========data.head[0]=====%c\n",data.head[0]);
printf("===========data.head[1]=====%c\n",data.head[1]);
if((data.head[0] == NULL) || (data.head[1] == NULL))
{
return -1;
}
while (pos < needRecv)
{
len0 = recv(sockConn, (char*)(&data) + pos + 2, needRecv - pos, 0);
if (len0 < 0)
{
printf("Server Recieve Data Failed!\n");
return -1;
break;
}
pos += len0;
}
if((data.head[0] != 'a') || (data.head[1] != 'b'))
{
return -1;
}
if((data.head[0] == 'c') && (data.head[1] == 'd'))
{
return 0;
}
for (int j = 0; j < IMG_HEIGHT / PACKAGE_NUM; j++)
{
int num2 = j * IMG_WIDTH * 3;
uchar* ucdata = img.ptr<uchar>(j);
for (int k = 0; k < IMG_WIDTH * 3; k++)
{
ucdata[k] = data.buf[num2 + k];
}
}
image = img;
returnflag = 1;
if(returnflag == 1)
return 1;
else
return -1;
}