一、概述

内容:由Client客户端采集摄像头图像后经Socket传输到Server服务器端再显示出来。本实验在同一台电脑上实验,即运行服务器程序,又跑客户端程序,也就是说通过socket编程来实现数据的自发自收,这一步通过了接下来跑服务器和客户端分开的实验就简单了。
实验平台: VS2013 + opencv2.4.11(Windows 7)
说明:近期项目需要进行图像的采集传输任务,遂在网上寻找,并进行了些修改,记录在此。

二、实现

1、TCP协议通信的一般步骤是:

客户端:

1、创建一个socket,用函数socket();
  2、设置socket属性,用函数setsockopt();* 可选
  3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
  4、设置要连接的对方的IP地址和端口等属性;
  5、连接服务器,用函数connect();
  6、收发数据,用函数send()和recv(),或者read()和write();
  7、关闭网络连接;

服务器端:

1、创建一个socket,用函数socket();
  2、设置socket属性,用函数setsockopt(); * 可选
  3、绑定IP地址、端口等信息到socket上,用函数bind();
  4、开启监听,用函数listen();
  5、接收客户端上来的连接,用函数accept();
  6、收发数据,用函数send()和recv(),或者read()和write();
  7、关闭网络连接;
  8、关闭监听;


2、Client 的实现(数据发送)

//  Client.cpp 主函数
//  基于OpenCV和Winsock的图像传输(发送)#include "WinsockMatTransmissionClient.h"  int main()
{WinsockMatTransmissionClient socketMat;if (socketMat.socketConnect("192.168.191.1", 6666) < 0) //地址自行设置{return 0;}cv::VideoCapture capture(0);cv::Mat frame;while (1){if (!capture.isOpened())return 0;capture >> frame;imshow("client", frame);cv::waitKey(30);if (frame.empty())return 0;socketMat.transmit(frame);}socketMat.socketDisconnect();return 0;
}

数据的发送——WinsockMatTransmissionClient.h

//  WinsockMatTransmissionClient.h
//  基于OpenCV和Winsock的图像传输(发送)#ifndef __WINSOCKMATTRANSMISSIONCLIENT_H__
#define __WINSOCKMATTRANSMISSIONCLIENT_H__
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include <stdio.h>
#include <Winsock2.h>  #pragma comment(lib,"WS2_32.lib")  //待传输图像默认大小为 640*480,可修改
#define IMG_WIDTH 640   // 需传输图像的宽
#define IMG_HEIGHT 480  // 需传输图像的高
//默认格式为CV_8UC3
#define BUFFER_SIZE IMG_WIDTH*IMG_HEIGHT*3/32  struct sentbuf
{char buf[BUFFER_SIZE];int flag;
};class WinsockMatTransmissionClient
{public:WinsockMatTransmissionClient(void);~WinsockMatTransmissionClient(void);private: SOCKET sockClient;struct sentbuf data;public:// 打开socket连接  // params : IP      服务器的ip地址  //          PORT    传输端口  // return : -1      连接失败  //          1       连接成功  int socketConnect(const char* IP, int PORT);// 传输图像  // params : image 待传输图像  // return : -1      传输失败  //          1       传输成功  int transmit(cv::Mat image);// 断开socket连接  void socketDisconnect(void);
};#endif  

数据的发送——WinsockMatTransmissionClient.cpp

//  WinsockMatTransmissionClient.cpp
//  基于OpenCV和Winsock的图像传输(发送)#include "WinsockMatTransmissionClient.h"  WinsockMatTransmissionClient::WinsockMatTransmissionClient(void)
{
}WinsockMatTransmissionClient::~WinsockMatTransmissionClient(void)
{
}int WinsockMatTransmissionClient::socketConnect(const char* IP, int PORT)
{WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD(1, 1);err = WSAStartup(wVersionRequested, &wsaData);if (err != 0) {return -1;}if (LOBYTE(wsaData.wVersion) != 1 ||HIBYTE(wsaData.wVersion) != 1) {WSACleanup();return -1;}err = (sockClient = socket(AF_INET, SOCK_STREAM, 0));if (err < 0) {printf("create socket error: %s(errno: %d)\n\n", strerror(errno), errno);return -1;}else{printf("create socket successful!\nnow connect ...\n\n");}SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr = inet_addr(IP);addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(PORT);err = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));if (err < 0){printf("connect error: %s(errno: %d)\n\n", strerror(errno), errno);return -1;}else{printf("connect successful!\n\n");return 1;}
}void WinsockMatTransmissionClient::socketDisconnect(void)
{closesocket(sockClient);WSACleanup();
}int WinsockMatTransmissionClient::transmit(cv::Mat image)
{if (image.empty()){printf("empty image\n\n");return -1;}if (image.cols != IMG_WIDTH || image.rows != IMG_HEIGHT || image.type() != CV_8UC3){printf("the image must satisfy : cols == IMG_WIDTH(%d)  rows == IMG_HEIGHT(%d) type == CV_8UC3\n\n", IMG_WIDTH, IMG_HEIGHT);return -1;}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++){data.buf[num2 + j] = ucdata[j];}}if (k == 31)data.flag = 2;elsedata.flag = 1;if (send(sockClient, (char *)(&data), sizeof(data), 0) < 0){printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);return -1;}}
}

3、Server 的实现(数据接收)

//  Server.cpp 主函数
//  基于OpenCV和Winsock的图像传输(接收)#include "WinsockMatTransmissionServer.h"  int main()
{WinsockMatTransmissionServer socketMat;if (socketMat.socketConnect(6666) < 0){return 0;}cv::Mat image;while (1){if (socketMat.receive(image) > 0){cv::imshow("server", image);cv::waitKey(30);}}socketMat.socketDisconnect();return 0;
}

数据的接收——WinsockMatTransmissionServer.h

//  WinsockMatTransmissionServer.h
//  基于OpenCV和Winsock的图像传输(接收)#ifndef __WINSOCKMATTRANSMISSIONSEVER_H__
#define __WINSOCKMATTRANSMISSIONSEVER_H__  #include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include <stdio.h>
#include <Winsock2.h>  #pragma comment(lib,"WS2_32.lib")  //待传输图像默认大小为 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;
};class WinsockMatTransmissionServer
{public:WinsockMatTransmissionServer(void);~WinsockMatTransmissionServer(void);private: SOCKET sockConn;struct recvbuf data;public:// 打开socket连接  // params : PORT    传输端口  // return : -1      连接失败  //          1       连接成功  int socketConnect(int PORT);// 传输图像  // params : image   待接收图像  // return : -1      接收失败  //          1       接收成功  int receive(cv::Mat& image);// 断开socket连接  void socketDisconnect(void);
};#endif 

数据的接收——WinsockMatTransmissionServer.cpp

//  WinsockMatTransmissionServer.cpp
//  基于OpenCV和Winsock的图像传输(接收)//  基于OpenCV和Winsock的图像传输(接收)#include <iostream>
#include "WinsockMatTransmissionServer.h"  WinsockMatTransmissionServer::WinsockMatTransmissionServer(void)
{
}WinsockMatTransmissionServer::~WinsockMatTransmissionServer(void)
{
}int WinsockMatTransmissionServer::socketConnect(int PORT)
{WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD(1, 1);err = WSAStartup(wVersionRequested, &wsaData);if (err != 0){return -1;}if (LOBYTE(wsaData.wVersion) != 1 ||HIBYTE(wsaData.wVersion) != 1){WSACleanup();return -1;}SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(PORT);bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));listen(sockSrv, 5);SOCKADDR_IN addrClient;int len = sizeof(SOCKADDR);sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);int nRecvBuf = 1024 * 1024 * 10;setsockopt(sockConn, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int));
}void WinsockMatTransmissionServer::socketDisconnect(void)
{closesocket(sockConn);
}int WinsockMatTransmissionServer::receive(cv::Mat& image)
{cv::Mat img(IMG_HEIGHT, IMG_WIDTH, CV_8UC3, cv::Scalar(0));int needRecv = sizeof(recvbuf);  //28804int count = 0;extern int errno;while (1){for (int i = 0; i < 32; i++){int pos = 0;int len0 = 0;while (pos < needRecv){len0 = recv(sockConn, (char*)(&data) + pos, needRecv - pos, 0);if (len0 < 0){printf("Server Recieve Data Failed!\n");return -1;}pos += len0;}count = count + data.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.buf[num2 + k];}}if (data.flag == 2){if (count == 33){image = img;return 1;count = 0;}else{count = 0;i = 0;}}}}
}

三、结果

Client端:

Server端:

OpenCV结合socket进行实时视频传输(TCP协议)相关推荐

  1. socket 网络通信(基于tcp协议)以及粘包解决方案

    socket 网络通信(基于tcp协议)以及粘包解决方案 参考文章: (1)socket 网络通信(基于tcp协议)以及粘包解决方案 (2)https://www.cnblogs.com/amiee- ...

  2. Socket 系统调用深入研究(TCP协议的整个通信过程)

    说明 本文主要参考的原文:Know your TCP system call sequences socket api可以参考我的博客:socket API 介绍 TCP DEMO:tcp demo ...

  3. java socket 通信协议_java 基于TCP协议的Socket编程和通信

    java 基于 TCP 协议的 Socket 编程和通信 在网络通讯中,第一次主动发起通讯的程序被称作客户 端 (Client) 程序, 简称客户端, 而在第一次通讯中等待连接的 程序被称作服务器端 ...

  4. 基于TCP协议的Socket网络通信

    前言 一. 什么是网络(了解七层网络模型)? 二. 什么是TCP/UDP协议? 三.什么是socket? 定义 四.基于TCP协议的socket通信的实现步骤是怎样的? 客户端的实现 服务端的实现 测 ...

  5. 【计算机网络】传输层 : 总结 ( TCP / UDP 协议 | 寻址与端口 | UDP 协议 | TCP 协议特点 | TCP 连接释放 | TCP 流量控制 | TCP 拥塞控制 ) ★★★

    文章目录 一.传输层 TCP / UDP 协议 ★ 二.寻址端口号 ★ 三.UDP 协议特点 四.UDP 协议首部格式 五.UDP 校验 六.TCP 协议 特点 ★ 七.TCP 报文段首部格式 八.T ...

  6. 【计算机网络】传输层 : TCP 协议 ( TCP 协议特点 | TCP 报文段首部格式 | TCP 报文段控制位 )

    文章目录 一.TCP 协议 特点 二.TCP 报文段首部格式 三.TCP 报文段首部 666 控制位 一.TCP 协议 特点 TCP 协议 特点 : ① 面向连接 : TCP 协议的连接是 " ...

  7. 什么是SOCKET,什么是TCP,什么是HTTP?三者之间的关系和差异(面试常问)

    该文章内容为作者结合多篇博文的总结,自行记录的理论笔记,方便查看. 一.SOCKET 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本单元,它是网络通信过程中端点的抽象表示. ...

  8. 计算机视觉——利用openCV与Socket结合进行远程摄像头实时视频传输并保存图片数据

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.TCP协议通信步骤 二.代码实现 1.客户端 2.服务端 三.IP设置方法 四.效果演示 前言 本文的内容是利用o ...

  9. Socket编程(C语言实现)——TCP协议(网络间通信AF_INET)的流式(SOCK_STREAM)+报式(SOCK_DGRAM)传输【多线程+循环监听】

    Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服 ...

最新文章

  1. python16进制字节序_第 1 章 套接字、IPv4和简单的客户端/服务器编程
  2. Python原来这么厉害,我震惊了!
  3. php strpo函数,php strpos函数有什么用
  4. 安装Qemu-6.1.0
  5. linux服务器忘记ssh密码_【Linux】配置linux服务器之间ssh不用密码访问
  6. 华为路由交换常见配置
  7. 解决 el-autocomplete 不显示及没数据时闪一下的问题
  8. kubernetes存储系统介绍(Volume、PV、dynamic provisioning,阿里云服务器nfs创建pv,hostpath创建pv)
  9. 详解MySQL中EXPLAIN解释命令(转)
  10. windows tcp ping 端口工具及使用方法
  11. 《系统工程》--课程笔记二(系统工程方法论)
  12. 多窗直播 截屏录制——UC问鼎全球首款直播浏览器
  13. 如何学习硬件设计——理论篇
  14. Yolov5中使用Resnet18作为主干网络
  15. 前端实现Thing.js 3D模型展示Demo
  16. 3D视觉感知市场规模现状及行业发展前景分析
  17. 以前用C++实现的RMM分词类型
  18. 饮食男女,人之大欲--nbsp;《饮食…
  19. 【Leetcode】对 矩 阵 螺 旋 输 出 java/c++
  20. BZOJ4811: [Ynoi2017]由乃的OJ 重链剖分

热门文章

  1. JavaWeb 入门篇(2)Hello Servlet!!!
  2. 想学python怎么学习_新手如何自学python课程?
  3. python获取数组中大于某一阈值的那些索引值_使用Python+OpenCV进行实时车道检测...
  4. websocket 代理tcp_netty实现websocket请求实战
  5. 修改oracle日志大小,修改Oracle重做日志文件大小
  6. webpack引入iview.css,解决webpack+Vue引入iView找不到字体文件的问题
  7. t184卡西欧计算机玩游戏,中学回忆——卡西欧 FX-82ES 科学计算器 晒物
  8. python 笔试题 英方_经典算法题 :找字符串中的逆序对(百度笔试题)
  9. python引入jit_从numba导入jit
  10. 如何利用python进行数据分析统计服_利用Python进行数据分析