首页 > 学院 > 开发设计 > 正文

利用UDP协议进行图像传输

2019-11-06 09:49:34
字体:
来源:转载
供稿:网友

由于项目需要,自己实现了UPD协议下图像的快速无丢失传输,测试数据是Egtest01图像库,实现了PC和嵌入式端的图像传输,传输+读写的速度可以实现10+M/S。

服务器端程序

#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.113"//"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/n");          exit(1);      }else      {          PRintf("socket success/n");      }      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/n");      struct timeval tpstart,tpend;      double timeuse;      gettimeofday(&tpstart,NULL);      int index=0;      for(index=0;index<1821;index++)      {          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/n");              exit(1);          }else          {              printf("request for %s success/n",send_buf);          }          //printf("begin receive/n");          sprintf(recv_path,"/opt/imagedata/egtest01_bmp/%s",send_buf);          FILE *fd=fopen(recv_path,"wb+");          int onums=0;          while(fd==NULL)          {              onums++;              perror("open fail");              printf("try to open %s for receiving %d/n",recv_path,onums);              fd=fopen(recv_path,"wb+");                     //exit(1);          }          long int position=0;          unsigned long saposition=0;          int recv9=0;          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/n",recv_num);              if(recv_num<0)              {                //perror("receive error");                fseek(fd,saposition,SEEK_SET);                position=saposition;                send_num=sendto(sock_fd,send_again,18,0,(struct sockaddr*)&addr_serv,dest_len);                continue;              }              else if(recv_num==9&&(position==921654||recv9>=3))              {                fclose(fd);                break;//接收一个文件结束              }              else if(recv_num==51200||recv_num==54)              {                //printf("position is in %ld/n",position);                fseek(fd,position,SEEK_SET);                fwrite(recv_buf,1,recv_num,fd);                saposition=position;                position+=recv_num;                send_num=sendto(sock_fd,recv_over,12,0,(struct sockaddr*)&addr_serv,dest_len);              }              else              {                 //printf("recv_num error: %d/n",recv_num);                 recv9++;                 fseek(fd,saposition,SEEK_SET);                 position=saposition;                 continue;                 //exit(-1);              }          }       }      close(sock_fd);      gettimeofday(&tpend,NULL);      timeuse=1000*(tpend.tv_sec-tpstart.tv_sec)+(tpend.tv_usec-tpstart.tv_usec)/1000;      printf("processor time is %lf ms/n",timeuse);      return 0;          }  

客户端程序

#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/n");          exit(1);      }else      {          printf("socket success/n");      }      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/n");          exit(1);      }else      {          printf("bind success/n");      }      //设置超时时间      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/n");          unsigned long saposition;          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_buf: %s/n",recv_num,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;            if(fd==NULL)//文件最后一个包出错需要重发的情况            {              fd=fopen(send_path,"rb");              fseek(fd,saposition,SEEK_SET);            }          }else        {            if(fd!=NULL)            fclose(fd);            printf("receive request success : %s/n",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/n",send_path);              exit(1);            }             recv_ask_flag=true;             send_over_flag=false;           }          //printf("begin send/n");          long int position=0;          while(recv_ask_flag&&fd!=NULL)          {                 position=ftell(fd);              if(fread(send_buf,1,MAX_DATA,fd)==0)              {                //perror("read file");                recv_ask_flag=false;                send_again_flag=false;                send_over_flag=true;                break;              }              //printf("position is in %ld/n",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/n",send_num);              if(send_num<0||send_again_flag==true)              {                //perror("send error");                 fseek(fd,saposition,SEEK_SET);                send_again_flag=false;                continue;              }              saposition=position;              recv_ask_flag=false;              send_again_flag=false;          }          if(send_over_flag&&position==921654&&fd!=NULL)          {             send_num=sendto(sock_fd,send_over,9,0,(struct sockaddr*)&addr_client,client_len);             if(fd!=NULL)             {               fclose(fd);               fd=NULL;             }          }      }      close(sock_fd);      return 0;  }  


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表