UDP议定书图像高速传输无损失程序

下面的程序实现UDP没有图像数据的高速传输协议损耗,测试数据egtest01图片库,实现PC和图像的传输嵌入式结束。变速箱+读写速度可以达到10+M/S。考



server端程序

#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;   
        
}



client程序

#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;
    
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

posted @ 2015-10-17 19:43  zfyouxi  阅读(283)  评论(0编辑  收藏  举报