TCP/UDP传输摄像头采集的数据(opencv)
来源:互联网 发布:菜鸟网络 工作强度 编辑:程序博客网 时间:2024/05/22 11:40
server
本博客是一个服务器和客户端的程序,可以直接用vs创建2个工程,复制下面代码,替代main函数,前提要配好opencv库,还要在客户端有摄像头,本博客是用TCP传输实现,(Tcp对包的数据大小没有限制)虽然封装了UDP 的接口,但是udp最大的包有限制(1500字节左右),所以一帧数据一个包发送不完,需要分包和解包,这部分没有实现
// server#include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") #include "opencv2/opencv.hpp"using namespace cv;typedef struct socket_info{ SOCKET serSocket; int numClient; sockaddr_in remoteAddr[10]; int nAddrLen[10];}Socket_Udp_Server_Info;typedef struct socket_info_tcp{ SOCKET slisten; int numClient; SOCKET sClient[10]; // 记录客户端的套接字 sockaddr_in remoteAddr[10];}Socket_Tcp_Server_Info;Socket_Udp_Server_Info * initUdpServer(){ int i = 0; Socket_Udp_Server_Info * mSocketInfo = (Socket_Udp_Server_Info *)malloc(sizeof(Socket_Udp_Server_Info)); WSADATA wsaData; WORD sockVersion = MAKEWORD(2, 2); if (WSAStartup(sockVersion, &wsaData) != 0) { return 0; } mSocketInfo->serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (mSocketInfo->serSocket == INVALID_SOCKET) { printf("socket error !"); return 0; } sockaddr_in serAddr; serAddr.sin_family = AF_INET; serAddr.sin_port = htons(8888); serAddr.sin_addr.S_un.S_addr = INADDR_ANY; if (bind(mSocketInfo->serSocket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) { printf("bind error !"); closesocket(mSocketInfo->serSocket); return 0; } else { printf("bind succeed ! \n"); } mSocketInfo->nAddrLen[0] = sizeof(sockaddr_in); return mSocketInfo;}// 结束时候调用void unitUdpServer(Socket_Udp_Server_Info * mSocketInfo){ closesocket(mSocketInfo->serSocket); WSACleanup(); // 结束ws2_32.lib}Socket_Tcp_Server_Info * initTcpServer(){ int i = 0; Socket_Tcp_Server_Info * mSocketInfo = (Socket_Tcp_Server_Info *)malloc(sizeof(Socket_Tcp_Server_Info)); mSocketInfo->numClient = 1; // 只连接一个客户端 WORD sockVersion = MAKEWORD(2, 2); WSADATA wsaData; if (WSAStartup(sockVersion, &wsaData) != 0) { return 0; } //创建套接字 mSocketInfo->slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (mSocketInfo->slisten == INVALID_SOCKET) { printf("socket error !"); return 0; } //绑定IP和端口 sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(8888); sin.sin_addr.S_un.S_addr = INADDR_ANY; if (bind(mSocketInfo->slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR) { printf("bind error !"); } //开始监听 if (listen(mSocketInfo->slisten, 5) == SOCKET_ERROR) { printf("listen error !"); return 0; } int nAddrlen = sizeof(mSocketInfo->remoteAddr[0]); for (i = 0; i < 1; i++) // 如果要接收很多客户端就要循环多次,这里只有一个客户端,如果多个客户端,要多线程处理 { mSocketInfo->sClient[i] = accept(mSocketInfo->slisten, (SOCKADDR *)&mSocketInfo->remoteAddr[i], &nAddrlen); if (mSocketInfo->sClient[i] == INVALID_SOCKET) { printf("accept error !"); continue; } else { printf("accept success 接收到一个连接 ! \n"); } } return mSocketInfo;}// 结束时候调用void unitTcpServer(Socket_Tcp_Server_Info * mSocketInfo){ closesocket(mSocketInfo->slisten); for (int i = 0; i < mSocketInfo->numClient; i++) { closesocket(mSocketInfo->sClient[i]); } WSACleanup(); // 结束ws2_32.lib}int main(){ Socket_Udp_Server_Info * mSocketUdpServerInfo = initUdpServer(); Socket_Tcp_Server_Info * mSocketTcpServerInfo = initTcpServer(); int info[3]; int flag = 0; int ret = 0; recv(mSocketTcpServerInfo->sClient[0], (char *)info, sizeof(int) * 3, 0); int width = info[0]; int height = info[1]; int channel = info[2]; int bufferSize = width * height * channel; flag = 1; ret = send(mSocketTcpServerInfo->sClient[0], (char *)(&flag), sizeof(int), 0); if (ret == sizeof(int)) { printf("flag re succeed \n"); } char * revBuffer = (char *)malloc(sizeof(char) * bufferSize); Mat reviMat = Mat(height, width, CV_8UC3); while (1) { //ret = recvfrom(mSocketUdpServerInfo->serSocket, revBuffer, bufferSize, 0, (sockaddr *)&mSocketUdpServerInfo->remoteAddr[0], &mSocketUdpServerInfo->nAddrLen[0]); ret = recv(mSocketTcpServerInfo->sClient[0], revBuffer, bufferSize, 0); printf("server ret = %d \n", ret); if (ret == bufferSize) { memcpy(reviMat.data, revBuffer, bufferSize); imshow("revice", reviMat); waitKey(2); } } return 0;}
client
// client#include <WINSOCK2.H> #include <STDIO.H> #include "opencv2/opencv.hpp"#pragma comment(lib,"ws2_32.lib") using namespace cv;typedef struct socket_info{ SOCKET sclient; sockaddr_in sin; int len;}Socket_Udp_Client_Info;typedef struct socket_info_tcp{ SOCKET sclient;}Socket_Tcp_Client_Info;Socket_Udp_Client_Info * initUdpClient(){ Socket_Udp_Client_Info * mSocketInfo = (Socket_Udp_Client_Info *)malloc(sizeof(Socket_Udp_Client_Info)); WORD socketVersion = MAKEWORD(2, 2); WSADATA wsaData; if (WSAStartup(socketVersion, &wsaData) != 0) { return 0; } mSocketInfo->sclient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); mSocketInfo->sin.sin_family = AF_INET; mSocketInfo->sin.sin_port = htons(8888); mSocketInfo->sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); mSocketInfo->len = sizeof(mSocketInfo->sin); return mSocketInfo;}void unitUdpClient(Socket_Udp_Client_Info * mSocketInfo){ closesocket(mSocketInfo->sclient); WSACleanup();}Socket_Tcp_Client_Info * initTcpClient(){ Socket_Tcp_Client_Info * mSocketInfo = (Socket_Tcp_Client_Info *)malloc(sizeof(Socket_Tcp_Client_Info)); WORD sockVersion = MAKEWORD(2, 2); WSADATA data; if (WSAStartup(sockVersion, &data) != 0) { return 0; } mSocketInfo->sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (mSocketInfo->sclient == INVALID_SOCKET) { printf("invalid socket !"); return 0; } sockaddr_in serAddr; serAddr.sin_family = AF_INET; serAddr.sin_port = htons(8888); serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); if (connect(mSocketInfo->sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) { printf("connect error !"); closesocket(mSocketInfo->sclient); return 0; } return mSocketInfo;}void unitTcpClient(Socket_Tcp_Client_Info * mSocketInfo){ closesocket(mSocketInfo->sclient); WSACleanup();}int main(){ Socket_Udp_Client_Info * mSocketUdpClientInfo = initUdpClient(); Socket_Tcp_Client_Info * mSocketTcpClientInfo = initTcpClient(); cv::VideoCapture capture(0); // 打开摄像头 cv::Mat imageTemp; capture >> imageTemp; int info[3]; int ret = 0; int flag = 0; info[0] = imageTemp.cols; info[1] = imageTemp.rows; info[2] = imageTemp.channels(); // 先把宽高和通道数传过去 ret = send(mSocketTcpClientInfo->sclient, (char *)info, sizeof(int) * 3, 0); if (ret == sizeof(int) * 3) { printf("client send width height channel succeed \n"); } recv(mSocketTcpClientInfo->sclient, (char *)(&flag), sizeof(int), 0); if (flag == 1) { printf("client dui fang succeed recevied \n"); } printf("Image size: [%d %d]\n", imageTemp.cols, imageTemp.rows); while (1) { capture >> imageTemp; // 发送的包的大小不能超过1500个字节 //ret = sendto(mSocketUdpClientInfo->sclient, (char *)(imageTemp.data), imageTemp.cols, 0, (sockaddr *)&mSocketUdpClientInfo->sin, mSocketUdpClientInfo->len); ret = send(mSocketTcpClientInfo->sclient, (char *)(imageTemp.data), imageTemp.cols * imageTemp.rows * imageTemp.channels(), 0); printf("ret = %d \n", ret); imshow("send", imageTemp); cv::waitKey(30); } return 0;}
阅读全文
1 0
- TCP/UDP传输摄像头采集的数据(opencv)
- Linux下基于OpenCV的摄像头数据采集与传输
- opencv之采集摄像头数据
- ROS&OpenCV进行摄像头数据的采集与订阅发布
- opencv采集视频/摄像头数据并保存
- 为什么TCP传输单元叫作TCP报文段,而UDP的叫作UDP数据报
- 见鬼的摄像头与udp协议传输
- Gstreamer实现摄像头的远程采集,udp传输,本地显示和保存为AVI文件 发送端
- Gstreamer实现摄像头的远程采集,udp传输,本地显示和保存为AVI文件 接收保存显示端
- Gstreamer实现摄像头的远程采集,udp传输,本地显示和保存为AVI文件 发送端
- Gstreamer实现摄像头的远程采集,udp传输,本地显示和保存为AVI文件 接收保存显示端
- 网络编程 UDP TCP传输数据
- Python+OpenCV采集本地摄像头的视频
- opencv下摄像头的采集和保存
- opencv摄像头视频采集(Windows系统)
- 【OpenCV】摄像头顺序采集
- tcp 数据的传输
- Linux: 两个USB摄像头的数据采集问题(嵌入式)
- 配置Homestead中homestead.yaml的内容
- 无限轮播图+pulltorefresh+侧滑
- java 设计模式☞观察者模式
- 初识红黑树
- PathRemoveFileSpec函数的作用是将路径末尾的文件名和反斜杠去掉
- TCP/UDP传输摄像头采集的数据(opencv)
- Tomcat 安装
- Python 操作FTP文件,上传下载文件
- 深入理解javascript原型和闭包(14)——从【自由变量】到【作用域链】
- 环信发送名片
- Java EE开发第七章:JDBC开发之C3P0连接池的使用(常用)
- 城市列表简单用法
- 美团抽奖算法js
- 引用句柄 bad 非法引用句柄 是一样的