服务器端
#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>的前面