c++ socket服务器端和客户端实例(实现简单监控功能)

服务器端

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <WinSock2.h>
#include <string>
#include <iostream>
#include <Windows.h>
#pragma comment (lib, "ws2_32.lib")
#pragma warning(disable : 4996)
using namespace cv;
using namespace std;
//待传输图像默认大小为 640*480,可修改
#define IMG_WIDTH 640	// 需传输图像的宽
#define IMG_HEIGHT 480	// 需传输图像的高
//默认格式为CV_8UC3
#define BUFFER_SIZE IMG_WIDTH*IMG_HEIGHT*3/32 
struct recvbuf
{
	char buf[BUFFER_SIZE];
	int flag;
	char b[30];
};
recvbuf data_recv;
Mat recieveMat(SOCKET sockServer);
int main() {

	//初始化 DLL
	WSADATA data;
	WORD w = MAKEWORD(2, 0);
	::WSAStartup(w, &data);
	// 创建套接字
	SOCKET s;
	s = ::socket(AF_INET, SOCK_STREAM, 0);

	// 构造ip地址
	sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_addr.S_un.S_addr = inet_addr("202.113.76.34");//ip地址是服务器端ip地址
	addr.sin_port = htons(1234);


	::bind(s, (SOCKADDR*)&addr, sizeof(SOCKADDR));
	//进入监听状态
	listen(s, 5);
	//接收客户端请求
	SOCKADDR clntAddr;
	int nSize = sizeof(SOCKADDR);
	SOCKET clntSock = accept(s, (SOCKADDR*)&clntAddr, &nSize);
	std::cout << "linked\n";

	/*Mat frame = recieveMat(s);
	if (frame.data) imshow("Camera", frame);
	waitKey(0);*/
	while (true) {
		Mat frame = recieveMat(clntSock);
		if (frame.data) imshow("Camera", frame);
		if (waitKey(1) >= 0)break;
	}
	::closesocket(s);
	::closesocket(clntSock);
	::WSACleanup();
}


Mat recieveMat(SOCKET sockServer) {
	Mat img(IMG_HEIGHT, IMG_WIDTH, CV_8UC3, cv::Scalar(0));
	int needRecv = sizeof(recvbuf);
	int count = 0;
	for (int i = 0; i < 32; i++) {
		int pos = 0;
		int len0 = 0;
		while (pos < needRecv) {
			len0 = recv(sockServer, (char*)(&data_recv) + pos, needRecv - pos, 0);
			pos += len0;
		}
		count = count + data_recv.flag;
		int num1 = IMG_HEIGHT / 32 * i;
		for (int j = 0; j < IMG_HEIGHT / 32; j++) {
			int num2 = j * IMG_WIDTH * 3;
			uchar* ucdata = img.ptr<uchar>(j + num1);
			for (int k = 0; k < IMG_WIDTH * 3; k++) {
				ucdata[k] = data_recv.buf[num2 + k];
			}
		}
		if (data_recv.flag == 2) {
			if (count == 33) {
				string a(data_recv.b);
				cout << a << endl;
				return img;
			}
			else {
				count = 0;
				i = 0;
			}
		}
	}
}

客户端

#include "stdafx.h"
#include "opencv2/opencv.hpp"
#include <string>
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll
#pragma warning(disable : 4996)

//待传输图像默认大小为 640*480,可修改
#define IMG_WIDTH 640	// 需传输图像的宽
#define IMG_HEIGHT 480	// 需传输图像的高
//默认格式为CV_8UC3
#define BUFFER_SIZE IMG_WIDTH*IMG_HEIGHT*3/32 
using namespace cv;
using namespace std;

struct sentbuf {
	char buf[BUFFER_SIZE];
	int flag;
	char b[30];
};
sentbuf dataSend;
void sendMat(SOCKET sockClient, Mat image);
string testastring;
int main(int, char**)
{
	VideoCapture cap(0); // open the default camera
	if (!cap.isOpened())  // check if we succeeded
		return -1;
	Mat frame;
	//初始化 DLL
	WSADATA wsaData;
	::WSAStartup(MAKEWORD(2, 0), &wsaData);
	//创建套接字
	SOCKET servSock = ::socket(AF_INET, SOCK_STREAM, 0);

	//绑定套接字
	sockaddr_in sockAddr;
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_addr.S_un.S_addr = inet_addr("202.113.76.34");//该ip地址是服务器端ip地址
	sockAddr.sin_port = htons(1234);

	std::cout << "connecting\n";
	::connect(servSock, (sockaddr*)&sockAddr, sizeof(sockAddr));
	std::cout << "linked\n";

	int count = 0;
	for (;;)
	{
		cap >> frame; // get a new frame from camera
		testastring = "D://put//a.bmp" + to_string(count);
		count++;
		sendMat(servSock, frame);
	}
	//cap >> frame; // get a new frame from camera
	/*Mat temp;
	temp = imread("F://abcd.png");
	resize(temp, frame, Size(640, 480));
	testastring = "D://put//a.bmp" + to_string(count);
	count++;
	sendMat(clntSock, frame);*/
	// the camera will be deinitialized automatically in VideoCapture destructor

	//关闭套接字
	closesocket(servSock);

	//终止 DLL 的使用
	WSACleanup();

	return 0;
}
void sendMat(SOCKET sockClient, Mat image) {
	memset(dataSend.b, 0, sizeof(dataSend.b) / sizeof(char));
	strcpy(dataSend.b, testastring.c_str());
	for (int k = 0; k < 32; k++) {
		int num1 = IMG_HEIGHT / 32 * k;
		for (int i = 0; i < IMG_HEIGHT / 32; i++) {
			int num2 = i * IMG_WIDTH * 3;
			uchar* ucdata = image.ptr<uchar>(i + num1);
			for (int j = 0; j < IMG_WIDTH * 3; j++) {
				dataSend.buf[num2 + j] = ucdata[j];
			}
		}
		if (k == 31)
			dataSend.flag = 2;
		else
			dataSend.flag = 1;
		send(sockClient, (char *)(&dataSend), sizeof(dataSend), 0);
	}
}

注意事项:
1.如果报错的话可以先考虑c++ ->预处理器 ->预处理器定义 ->加上_CRT_SECURE_NO_WARNINGS
2.要注意头文件#include <WinSock2.h>一定要在#include <Windows.h>的前面

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现Socket通信可以使用C++Socket API,可以通过以下步骤实现服务器和客户端同时收发消息: 1. 创建服务器Socket 使用socket()函数创建服务器Socket,可以指定协议、IP地址和端口号。例如: ```c++ int serverSocket = socket(AF_INET, SOCK_STREAM, 0); ``` 2. 绑定Socket和地址 使用bind()函数将Socket和服务器地址绑定,可以指定IP地址和端口号。例如: ```c++ struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = INADDR_ANY; serverAddress.sin_port = htons(PORT); bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)); ``` 其中,PORT是端口号。 3. 监听连接请求 使用listen()函数开始监听客户端连接请求。例如: ```c++ listen(serverSocket, 5); ``` 其中,第二个参数是等待连接队列的最大长度。 4. 接受连接请求 使用accept()函数接受客户端连接请求,可以得到一个新的Socket用于与客户端通信。例如: ```c++ struct sockaddr_in clientAddress; socklen_t clientAddressSize = sizeof(clientAddress); int clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddress, &clientAddressSize); ``` 5. 发送和接收消息 使用send()函数向客户端发送消息,使用recv()函数接收来自客户端的消息。例如: ```c++ char buffer[1024]; memset(buffer, 0, sizeof(buffer)); recv(clientSocket, buffer, sizeof(buffer), 0); cout << "Received message: " << buffer << endl; string message = "Hello, client!"; send(clientSocket, message.c_str(), message.length(), 0); ``` 6. 关闭Socket 使用close()函数关闭Socket。例如: ```c++ close(serverSocket); close(clientSocket); ``` 客户端实现类似,只需要创建一个客户端Socket连接服务器,然后发送和接收消息即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值