UDP协议来快速无丢失传输图像程序
来源:程序员人生 发布时间:2014-09-14 21:18:41 阅读次数:2576次
以下程序实现了UDP协议下无丢失快速的传输图像数据,测试数据是egtest01图像库,实现了PC和嵌入式端的图像传输,传输+读写的速度可以实现10+M/S,贴上代码可作为参考
服务器端程序
<span style="font-family:SimSun;font-size:18px;">#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SERV_PORT 3000
#define MAX_DATA 51200 //50kb
#define FILE_LENGTH 921654 //图片大小
#ifndef bool
#define bool int
#define true 1
#define false 0
#endif
int main(int argc,char* argv[])
{
int sock_fd;
int recv_num;
int send_num;
int client_len;
char recv_buf[20];
char send_buf[MAX_DATA];
char send_path[1024];
char send_over[9]="send over";
struct sockaddr_in addr_serv;
struct sockaddr_in addr_client;
FILE *fd=NULL;
sock_fd=socket(AF_INET,SOCK_DGRAM,0);
if(sock_fd<0)
{
perror("socket error
");
exit(1);
}else
{
printf("socket success
");
}
memset(&addr_serv,0,sizeof(struct sockaddr_in));
addr_serv.sin_family=AF_INET;
addr_serv.sin_port=htons(SERV_PORT);
addr_serv.sin_addr.s_addr=htonl(INADDR_ANY);//任意本地址
client_len=sizeof(struct sockaddr_in);
if(bind(sock_fd,(struct sockaddr*)&addr_serv,sizeof(struct sockaddr_in))<0)
{
perror("bind error
");
exit(1);
}else
{
printf("bind success
");
}
//设置超时时间
struct timeval tv_out;
tv_out.tv_sec=3;
tv_out.tv_usec=0;
setsockopt(sock_fd,SOL_SOCKET,SO_RCVTIMEO,&tv_out,sizeof(tv_out));
bool recv_ask_flag=true;
bool send_over_flag=false;
bool send_again_flag=false;
while(1)
{
printf("begin receive
");
memset(recv_buf,0,sizeof(recv_buf));
recv_num=recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr*)&addr_client,&client_len);
printf("recv_num: %d
",recv_num);
printf("recv_buf: %s
",recv_buf);
if(recv_num<0)
{
perror("receive error");
continue;
}else if(recv_num==12)
{
recv_ask_flag=true;
}else if(recv_num==18)
{
recv_ask_flag=true;
send_again_flag=true;
}
else
{
if(fd!=NULL)
fclose(fd);
printf("receive request success : %s
",recv_buf);
sprintf(send_path,"/opt/imagedata/egtest01_bmp/%s",recv_buf);
fd=fopen(send_path,"rb");
if(fd==NULL)
{
printf("fail to open %s for sending
",send_path);
exit(1);
}
recv_ask_flag=true;
send_over_flag=false;
}
//printf("begin send
");
long int position=0;
send_over_flag=false;
while(recv_ask_flag&&fd!=NULL)
{
position=ftell(fd);
if(fread(send_buf,1,MAX_DATA,fd)==0)
{
perror("read file");
fclose(fd);
fd=NULL;
recv_ask_flag=false;
send_again_flag=false;
send_over_flag=true;
break;
}
printf("position is in %ld
",position);
long int send_size=(position+MAX_DATA)>FILE_LENGTH?(FILE_LENGTH-position):MAX_DATA;
send_num=sendto(sock_fd,send_buf,send_size,0,(struct sockaddr*)&addr_client,client_len);
printf("send_num: %d
",send_num);
if(send_num<0||send_again_flag==true)
{
perror("send error");
fseek(fd,position,SEEK_SET);
send_again_flag=false;
continue;
}
recv_ask_flag=false;
send_again_flag=false;
}
if(send_over_flag)
{
send_num=sendto(sock_fd,send_over,9,0,(struct sockaddr*)&addr_client,client_len);
send_over_flag=false;
}
}
close(sock_fd);
return 0;
}
</span>
客户端程序
<span style="font-family:SimSun;font-size:18px;">#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#define DEST_PORT 3000
#define MAX_DATA 51200 //50kb
#define DEST_IP_ADDRESS "10.42.0.1" //"192.168.1.19"//"169.254.9.36"
#ifndef bool
#define bool int
#define true 1
#define false 0
#endif
int main(int argc,char* argv[])
{
int sock_fd;
int send_num;
int recv_num;
int dest_len;
char send_buf[100];
char recv_buf[MAX_DATA];
char recv_path[1024];
char recv_over[12]="receive over";
char send_again[18]="send package again";
struct sockaddr_in addr_serv;
sock_fd=socket(AF_INET,SOCK_DGRAM,0);
if(sock_fd<0)
{
perror("socket error
");
exit(1);
}else
{
printf("socket success
");
}
memset(&addr_serv,0,sizeof(struct sockaddr_in));
addr_serv.sin_family=AF_INET;
addr_serv.sin_port=htons(DEST_PORT);
addr_serv.sin_addr.s_addr=inet_addr(DEST_IP_ADDRESS);
dest_len=sizeof(struct sockaddr_in);
//设置超时时间
struct timeval tv_out;
tv_out.tv_sec=3;
tv_out.tv_usec=0;
setsockopt(sock_fd,SOL_SOCKET,SO_RCVTIMEO,&tv_out,sizeof(tv_out));
printf("begin send
");
struct timeval tpstart,tpend;
double timeuse;
gettimeofday(&tpstart,NULL);
int index=0;
for(index=0;index<1821;index++)//821
{
sprintf(send_buf,"frame%0.5d.bmp",index);
send_num=sendto(sock_fd,send_buf,14,0,(struct sockaddr*)&addr_serv,dest_len);
if(send_num<0)
{
perror("send error
");
exit(1);
}else
{
printf("request for %s success
",send_buf);
}
printf("begin receive
");
sprintf(recv_path,"/opt/imagedata/egtest01_bmp/%s",send_buf);
FILE *fd=fopen(recv_path,"wb");
if(fd==NULL)
{
printf("fail to open %s for receiving",recv_path);
exit(1);
}
/*
int onums=0;
while(fd==NULL)
{
onums++;
printf("try to open %s for receiving %d
",recv_path,onums);
fd=fopen(recv_path,"wb");
//exit(1);
}
*/
long int position=0;
bool recv_error_flag=false;
while(1)
{
memset(recv_buf,0,sizeof(recv_buf));
recv_num=recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr*)&addr_serv,&dest_len);//MSG_DONTWAIT
printf("recv_num: %d
",recv_num);
if(recv_num<0)
{
perror("receive error");
//recv_error_flag=true;
//break;
send_num=sendto(sock_fd,send_again,18,0,(struct sockaddr*)&addr_serv,dest_len);
continue;
}
else if(recv_num==9)
{
break;//接收一个文件结束
}
else
{
printf("position is in %ld
",position);
fseek(fd,position,SEEK_SET);
fwrite(recv_buf,1,recv_num,fd);
position+=recv_num;
send_num=sendto(sock_fd,recv_over,12,0,(struct sockaddr*)&addr_serv,dest_len);
}
}
if(recv_error_flag)
{
printf("receive error occur in %s
",recv_path);
exit(1);
}
else
{
//printf("have writen the received data to %s
",recv_path);
}
}
close(sock_fd);
gettimeofday(&tpend,NULL);
timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec;
timeuse/=1000;//ms
printf("processor time is %lf ms
",timeuse);
return 0;
}</span>
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠