您的位置:首页 > 其它

完整无线视频传输程序(已封装)

2012-09-19 22:55 351 查看
/*

* tcp.cpp

*

* Created on: 2012-5-20

* Author: root

*/

#include "tcp.h"

#include "opencv2/opencv.hpp"

/*defines*/

#define BUFFER_SIZE 1024

#define success 1

#define error 0

#define SERVER_PORT1 9000 //发送图片的端口

#define SERVER_PORT2 8000 //接收Rect的端口

#define SERVER_PORT3 7000 //接收控制指令的端口

#define SERVER_PORT4 10000 //发送UWB坐标回地面站

#define LISTEN_QUEUE 20

/*TCP varies*/

//int sock_fd; //定义端口文件描述符

/*以下全是外部变量*/

int new_server_socket1;

int new_server_socket2;

int new_server_socket3;

int new_server_socket4;

int server_socket1,server_socket2,server_socket3,server_socket4;

int pthread_ret1,pthread_ret2,pthread_ret3,pthread_ret4;

pthread_t id1,id2,id3,id4;

/*外部函数声明*/

extern void *ImgProc_Thread(void *id);

extern void *RecvRect_Thread(void *);

extern void *RecvCmd_Thread(void *id);

extern void *SendCoordinate2UGS(void *id);

FILE* stream; //文件指针

//char Image_Buffer[1024*100]; //将缓冲区设置为100k

//char buffer[BUFFER_SIZE]; //BUFFER_SIZE 1024b

int sock_buf_size=1024*100; //这是用来设置TCP缓冲区的

/*vector*/

vector<unsigned char>buf; //乘放的容器

vector<int> compression_params;

/*存放强制从vector转换来的图片数据*/

unsigned char* buffer;

/*function*/

void Server_Init(void)

{

/*设计思路,端口是对应应用的,所以每个连接使用的应该是不一样的端口(未经过验证)*/

struct sockaddr_in server_addr1; //定义地址结构,创建此服务器端口用来发送图像数据(端口是面向应用的)

struct sockaddr_in server_addr2; //连接此服务器端口用来接收地面站发过来的Rect

struct sockaddr_in server_addr3; //连接此服务器端口用来接收地面站发送来的控制指令

struct sockaddr_in server_addr4; //连接此服务器端口用来发送UWB坐标给UGS

struct sockaddr_in client_addr1;

struct sockaddr_in client_addr2;

struct sockaddr_in client_addr3;

struct sockaddr_in client_addr4;

socklen_t length1=sizeof(client_addr1);

socklen_t length2=sizeof(client_addr2);

socklen_t length3=sizeof(client_addr3);

socklen_t length4=sizeof(client_addr4);

bzero(&server_addr1,sizeof(server_addr1)); //全部置零

bzero(&server_addr2,sizeof(server_addr2));

bzero(&server_addr3,sizeof(server_addr3));

bzero(&server_addr4,sizeof(server_addr4));

//设置地址相关的属性

server_addr1.sin_family=AF_INET;

server_addr1.sin_addr.s_addr=htons(INADDR_ANY);

server_addr1.sin_port=htons(SERVER_PORT1);

server_addr2.sin_family=AF_INET;

server_addr2.sin_addr.s_addr=htons(INADDR_ANY);

server_addr2.sin_port=htons(SERVER_PORT2);

server_addr3.sin_family=AF_INET;

server_addr3.sin_addr.s_addr=htons(INADDR_ANY);

server_addr3.sin_port=htons(SERVER_PORT3);

server_addr4.sin_family=AF_INET;

server_addr4.sin_addr.s_addr=htons(INADDR_ANY);

server_addr4.sin_port=htons(SERVER_PORT4);

server_socket1=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket

if(server_socket1<0)

{

printf("socket1 create error\n");

exit(1);

}

server_socket2=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket

if(server_socket2<0)

{

printf("socket2 create error\n");

exit(1);

}

server_socket3=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket

if(server_socket3<0)

{

printf("socket3 create error\n");

exit(1);

}

server_socket4=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket

if(server_socket4<0)

{

printf("socket4 create error\n");

exit(1);

}

/*以下的函数还没确认是不是有用*/

// setsockopt( server_socket, SOL_SOCKET, SO_RCVBUF,

// (char *)&sock_buf_size, sizeof(sock_buf_size) );//设置接收缓冲区大小

/*第二步,端口和IP地址绑定:只有TCP的服务器端才需要这个步骤*/

if(bind(server_socket1,(struct sockaddr*)&server_addr1,sizeof(server_addr1)))

{

printf("IP address 1 bind error\n");

exit(1);

}

if(bind(server_socket2,(struct sockaddr*)&server_addr2,sizeof(server_addr2)))

{

printf("IP address 2 bind error\n");

exit(1);

}

if(bind(server_socket3,(struct sockaddr*)&server_addr3,sizeof(server_addr3)))

{

printf("IP address 3 bind error\n");

exit(1);

}

if(bind(server_socket4,(struct sockaddr*)&server_addr4,sizeof(server_addr4)))

{

printf("IP address 4 bind error\n");

exit(1);

}

/*服务器端监听server_socket端口,最多响应20个客户端请求*/

if(listen(server_socket1,LISTEN_QUEUE))

{

printf("Ground station 1 listen error\n");

exit(1);

}

printf("Video Transmission socket waiting for connection...\n");

if(listen(server_socket2,LISTEN_QUEUE))

{

printf("Ground station 2 listen error\n");

exit(1);

}

printf("TLD Rect receiving socket waiting connection...\n");

if(listen(server_socket3,LISTEN_QUEUE))

{

printf("Ground station 3 listen error\n");

exit(1);

}

printf("UAV Control CMD transmission socket waiting connection...\n");

if(listen(server_socket4,LISTEN_QUEUE))

{

printf("Ground station 3 listen error\n");

exit(1);

}

printf("UWB Coordinate Sending back socket waiting for connection...\n");

/*accept函数阻塞等待UAV的connect请求*/

/**************************************************************************************************/

/*考虑到accept()函数是阻塞模式,而连接请求又是确定的,故设计两次接收*/

new_server_socket1=accept(server_socket1,(struct sockaddr*)&client_addr1,&length1);

if(new_server_socket1==-1)

{

printf("accept1 error!\n");

exit(0);

}

printf("Connect with Ground Station sock1 successfully--GS IP:%s\n",inet_ntoa(client_addr1.sin_addr));

pthread_ret1=pthread_create(&id1,NULL,ImgProc_Thread,&new_server_socket1);//创建一个线程

/*************************************************************************************************/

/*已经将new_server_socket作为入口参数传入*/

new_server_socket2=accept(server_socket2,(struct sockaddr*)&client_addr2,&length2);

if(new_server_socket2==-1)

{

printf("accept2 error!\n");

exit(0);

}

printf("Connect with Ground Station sock2 successfully--GS IP:%s\n",inet_ntoa(client_addr2.sin_addr));

pthread_ret2=pthread_create(&id2,NULL,RecvRect_Thread,&new_server_socket2);//创建接收线程

/**********************************************************************************************/

new_server_socket3=accept(server_socket3,(struct sockaddr*)&client_addr3,&length3);

if(new_server_socket3==-1)

{

printf("accept3 error!\n");

}

printf("Connect with Ground Station sock3 successfully--GS IP:%s\n",inet_ntoa(client_addr3.sin_addr));

/*创建命令接收线程*/

pthread_ret3=pthread_create(&id3,NULL,RecvCmd_Thread,&new_server_socket3);

/*********************************************************************************************/

new_server_socket4=accept(server_socket4,(struct sockaddr*)&client_addr4,&length4);

if(new_server_socket4==-1)

{

printf("accept4 error!\n");

}

printf("Connect with Ground Station sock4 successfully--GS IP:%s\n",inet_ntoa(client_addr4.sin_addr));

/*创建命令接收线程*/

pthread_ret4=pthread_create(&id4,NULL,SendCoordinate2UGS,&new_server_socket4);

}

/*图像压缩编码并发送

* 入口参数:Mat image

* 出口参数:无

* 设计思路:不写成文件,直接存到内存,防止频繁硬盘读写耗费时间

* 最后修改:2012-5-24

* */

void Encode_Send(Mat img,int sock_fd)

{

int packet_cnt=0;

int send_len=0;

/*初始化全局参数*/

compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);

compression_params.push_back(60); //这是数值的大小反映的是图像的质量,取值范围:0-100

bool res = imencode(".jpg",img,buf,compression_params);

if(res==1)

{

// cout<<"Ecode one image done!"<<endl;

}

/*压缩处理的jpg图片尺寸不会超过int 65535*/

int left_length = buf.size(); //这个buf的大小是不是取出的图像数据的大小

//printf("total_length:%d\n",left_length);

/*先发送图片的大小*/

send(sock_fd,&left_length,sizeof(int),0);

//printf("Send jpg_len done!\n");

unsigned char* buffer; //存放从vector强制转换来的图像数据

/*添加动态内存管理2012-5-30*/

buffer = (unsigned char*)malloc(left_length*sizeof(unsigned char));

unsigned char dest[1024];

buffer=(unsigned char *)&buf[0];

while(left_length>1024)

{

send_len=send(sock_fd,memcpy(dest,buffer+packet_cnt*1024,1024),1024,0);

if(send_len<0)

printf("send error!\n");

left_length-=1024;

packet_cnt++;

}

/*剩余数据小于1024*/

send_len=send(sock_fd,memcpy(dest,buffer+packet_cnt*1024,left_length),left_length,0);

if(send_len!=left_length)

{

printf("last packets send error!\n");

}

else

{

//printf("Last packets len:%d\n",send_len);

}

}

/*接收bounding box的坐标值

* 入口参数:无

* 出口参数:Rect 即为接收到的矩形框*/

Rect Recv_BoundingBox(int sock_fd)

{

Rect box;

box.x=0;

box.y=0;

box.width=0;

box.height=0;

printf("wait Ground station to send back the Rect\n");

int len=recv(sock_fd,&box,sizeof(Rect),0);

if(len!=sizeof(Rect))

{

printf("Rect receive error!\n");

}

//printf("box.x: box.y: box.w: box.h: %d %d %d %d %d\n",box.x,box.y,box.width,box.height);

return box;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: