Github项目分析: socket_opencv(服务端)

项目源码: 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值