传输图像与传输其他什么数据在我看来并没有什么本质区别,主要是做好帧同步就行了(标定图片的开始行):
接收:
//头文件
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
int sockfd=socket(AF_INET,SOCK_DGRAM,0);//
//创建本机对象
struct sockaddr_in addr;
addr.sin_family =AF_INET;
addr.sin_port =htons(8888);//默认的端口号貌似要大于1024,这里随便给的是8888
addr.sin_addr.s_addr=inet_addr("192.168.1.0");//local ip
int ret =bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));//绑定本机端口
if(0>ret)
{
printf("bind\n");
return -1;
}
//创建对象机
struct sockaddr_in cli;//定义对象机的套接字
cli.sin_addr.s_addr=inet_addr("192.168.100.105");//对象机ip
socklen_t len=sizeof(cli);
unsigned char *data=new unsigned char[1824*940*3];//数据接收数据,传输的图像是1824*940的3//通道图像,分940个包,一次传一行,帧开始时会发送一个300的整数
//设置缓冲区
int optval=1824*940*10;
int optLEn=sizeof(int);
setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,(char*)&optval,optLEn);
while(1)
{
int buf;
recvfrom(sockfd,&buf,sizeof(buf),0,(struct sockaddr*)&cli,&len);
if(buf==300)
{
for(int i=0;i<940;i=i+1)
{
int rec=recvfrom(sockfd,data+i*1824*3,sizeof(unsigned char)*1824*3,0,(struct sockaddr*)&cli,&len);
}
cv::Mat im=cvCreateMat(940,1824,CV_8UC3);
memcpy(im.data,data,sizeof(unsigned char)*1824*940*3);
imshow("im",im);
cv::waitKey(1);
im.setTo(0);
memset(data,0,sizeof(unsigned char)*1824*940*3);
buf=0;
im.release();
}
}
close(sockfd);
发送:
sockfd=socket(AF_INET,SOCK_DGRAM,0);
addr.sin_family =AF_INET;
addr.sin_port =htons(8888);
addr.sin_addr.s_addr=inet_addr("192.168.1.0");//对象ip
len=sizeof(addr);
//设置缓冲区
int optval=1824*940*10;
setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,(char*)&optval,sizeof(int));
unsigned char *data=new unsigned char[gheight*gwidth*3];
while(1) {
memcpy(data,frame.data,sizeof(unsigned char)*gwidth*gheight*3);
int rec;
double start=getTickCount();
int flag=300;
sendto(sockfd,&flag,sizeof(flag),0,(struct sockaddr*)&addr,len);//发送帧头
for(int i=0;i<gheight;i++)
{
rec=sendto(sockfd,data+i*gwidth*3,sizeof(unsigned char)*gwidth*3,0,(struct sockaddr*)&addr,len);//一行一行的发送图像
}
}
结果:
int socket(int domain, int type, int protocol);
socket函数类似于open,用来打开一个网络连接,如果成功则返回一个网络文件描述符(int类型),之后我们操作这个网络连接都通过这个网络文件描述符。
dimain:域,网络域,网络地址范围(IPV4或IPV6等),也就是协议簇
type:指定套接字类型:SOCK_STREAM(TCP网络)、SOCK_DGRAM(UDP)、SOCK_SEQPACKET
protocol:指定协议,如果指定0,表示使用默认的协议
IPPROTO_IP IP传输协议
IPPROTO_TCP TCP传输协议
IPPROTO_UDP UDP协议
IPPROTO_SCTP SCTP传输协议
IPPROTO_ICMP ICMP协议
IPPROTO_IGMP IGMP协议
int PASCAL FAR sendto( SOCKET s, const char FAR* buf, int len, int flags,
const struct sockaddr FAR* to, int tolen);
s:一个标识套接口的描述字。
buf:包含待发送数据的缓冲区。
len:buf缓冲区中数据的长度。
flags:调用方式标志位。
to:(可选)指针,指向目的套接口的地址。
tolen:to所指地址的长度。
int PASCAL FAR recvfrom( SOCKET s, char FAR* buf, int len, int flags,
struct sockaddr FAR* from, int FAR* fromlen);
s:标识一个已连接套接口的描述字。
buf:接收数据缓冲区。
len:缓冲区长度。
flags:调用操作方式。
from:(可选)指针,指向装有源地址的缓冲区。
fromlen:(可选)指针,指向from缓冲区长度值。
(至于阻塞不阻塞的问题,我也没有了解那么多,至少这个已经可以用了)