家有琴童-读书简记 千脑智能-读书简记 笔记的方法-读书简记 心经抉隐-读书简记 刷新:重新发现商业与未来-读书简记 认知觉醒-读书简记 真希望我父母读过这本书-读书简记 模仿欲望-读书简记 蛤蟆先生去看心理医生-读书简记 十分钟冥想-读书简记 当我谈跑步时,我谈些什么-读书简记 乔布斯、禅与投资-读书简记 掌控习惯-读书简记 金钱心理学-读书简记 被讨厌的勇气-读书简记 身心合一的奇迹力量-读书简记 零极限-读书简记 投资最重要的事-读书简记 语言学的邀请-读书简记 更富有、更睿智、更快乐-读书简记 管理的常识-读书简记 卡片笔记写作法-读书简记 纳瓦尔宝典-读书简记 卓有成效的管理者-读书简记 贪婪的多巴胺-读书简记 清醒的活-读书简记 像哲学家一样生活:斯多葛哲学的生活艺术-读书简记 你是你吃出来的-读书简记 你可以跑的更快-读书简记 丹尼尔斯经典跑步训练法-读书简记 非暴力沟通-读书简记 异类-读书简记 稀缺-读书简记 为什么要睡觉-读书简记 事实-读书简记 世界上最快乐的人-读书简记 病毒学概览-读书简记 免疫学概览-读书简记 内观-读书简记 沟通的艺术-读书简记 你的生命有什么可能-读书简记 演化的故事-读书简记 经济学原理:宏观经济学分册-读书简记 经济学原理:微观经济学分册-读书简记 社会心理学-读书简记 追寻记忆的痕迹-读书简记 情绪-读书简记 远见:如何规划职业生涯3阶段-读书简记 存在主义心理治疗-读书简记 P·E·T父母效能训练-读书简记 彼得·林奇的成功投资-读书简记 2015-2020美国居民膳食指南-读书简记 中国居民膳食指南(2016)-读书简记 批判性思维-读书简记 代码大全-读书简记 游戏力-读书简记 成功,动机与目标-读书简记 基因组:人种自传23章-读书简记 YOU身体使用手册-读书简记 登天之梯-读书简记 为什么学生不喜欢上学-读书简记 请停止无效努力-读书简记 麦肯基疗法-读书简记 跟简七学理财-课程简记 指数基金投资指南(2017中信版)-读书简记 指数基金投资指南(2015雪球版)-读书简记 让大脑自由:释放天赋的12条定律-读书简记 养育的选择-读书简记 GPU高性能编程CUDA实战-读书简记 百万富翁快车道-读书简记 原则-读书简记 穷查理宝典-读书简记 C++并发编程实战-读书简记 哲学家们都干了些什么-读书简记 Effective C++-读书简记 通往财富自由之路-读书简记 Linux命令行与Shell脚本编程大全-读书简记 刻意练习-读书简记 写给大家看的设计书-读书简记 习惯的力量-读书简记 好好学习-读书简记 硅谷最受欢迎的情商课-读书简记 富爸爸,穷爸爸-读书简记 如何说孩子才会听,怎么听孩子才会说-读书简记 阻力最小之路-读书简记 ProGit-读书简记 思考:快与慢-读书简记 C语言深度剖析-读书简记 编程珠玑-读书简记 Head First 设计模式-读书简记 反脆弱-读书简记 我的阅读书单 小强升职记-读书简记 观呼吸-读书简记 黑客与画家-读书简记 晨间日记的奇迹-读书简记 如何高效学习-读书简记 即兴的智慧-读书简记 精力管理-读书简记 C++编程思想-读书简记 拖延心理学-读书简记 自控力-读书简记 伟大是熬出来的-读书简记 生命不能承受之轻-读书简记 高效能人士的七个习惯-读书简记 没有任何借口-读书简记 一分钟的你自己-读书简记 人生不设限-读书简记 暗时间-读书简记
家有琴童-读书简记 千脑智能-读书简记 笔记的方法-读书简记 心经抉隐-读书简记 刷新:重新发现商业与未来-读书简记 认知觉醒-读书简记 真希望我父母读过这本书-读书简记 模仿欲望-读书简记 蛤蟆先生去看心理医生-读书简记 十分钟冥想-读书简记 当我谈跑步时,我谈些什么-读书简记 乔布斯、禅与投资-读书简记 掌控习惯-读书简记 金钱心理学-读书简记 被讨厌的勇气-读书简记 身心合一的奇迹力量-读书简记 零极限-读书简记 投资最重要的事-读书简记 语言学的邀请-读书简记 更富有、更睿智、更快乐-读书简记 管理的常识-读书简记 卡片笔记写作法-读书简记 纳瓦尔宝典-读书简记 卓有成效的管理者-读书简记 贪婪的多巴胺-读书简记 清醒的活-读书简记 像哲学家一样生活:斯多葛哲学的生活艺术-读书简记 你是你吃出来的-读书简记 你可以跑的更快-读书简记 丹尼尔斯经典跑步训练法-读书简记 非暴力沟通-读书简记 异类-读书简记 稀缺-读书简记 为什么要睡觉-读书简记 事实-读书简记 世界上最快乐的人-读书简记 病毒学概览-读书简记 免疫学概览-读书简记 内观-读书简记 沟通的艺术-读书简记 你的生命有什么可能-读书简记 演化的故事-读书简记 经济学原理:宏观经济学分册-读书简记 经济学原理:微观经济学分册-读书简记 社会心理学-读书简记 追寻记忆的痕迹-读书简记 情绪-读书简记 远见:如何规划职业生涯3阶段-读书简记 存在主义心理治疗-读书简记 P·E·T父母效能训练-读书简记 彼得·林奇的成功投资-读书简记 2015-2020美国居民膳食指南-读书简记 中国居民膳食指南(2016)-读书简记 批判性思维-读书简记 代码大全-读书简记 游戏力-读书简记 成功,动机与目标-读书简记 基因组:人种自传23章-读书简记 YOU身体使用手册-读书简记 登天之梯-读书简记 为什么学生不喜欢上学-读书简记 请停止无效努力-读书简记 麦肯基疗法-读书简记 跟简七学理财-课程简记 指数基金投资指南(2017中信版)-读书简记 指数基金投资指南(2015雪球版)-读书简记 让大脑自由:释放天赋的12条定律-读书简记 养育的选择-读书简记 GPU高性能编程CUDA实战-读书简记 百万富翁快车道-读书简记 原则-读书简记 穷查理宝典-读书简记 C++并发编程实战-读书简记 哲学家们都干了些什么-读书简记 Effective C++-读书简记 通往财富自由之路-读书简记 Linux命令行与Shell脚本编程大全-读书简记 刻意练习-读书简记 写给大家看的设计书-读书简记 习惯的力量-读书简记 好好学习-读书简记 硅谷最受欢迎的情商课-读书简记 富爸爸,穷爸爸-读书简记 如何说孩子才会听,怎么听孩子才会说-读书简记 阻力最小之路-读书简记 ProGit-读书简记 思考:快与慢-读书简记 C语言深度剖析-读书简记 编程珠玑-读书简记 Head First 设计模式-读书简记 反脆弱-读书简记 小强升职记-读书简记 观呼吸-读书简记 黑客与画家-读书简记 晨间日记的奇迹-读书简记 如何高效学习-读书简记 即兴的智慧-读书简记 精力管理-读书简记 C++编程思想-读书简记 拖延心理学-读书简记 自控力-读书简记 伟大是熬出来的-读书简记 生命不能承受之轻-读书简记 高效能人士的七个习惯-读书简记 没有任何借口-读书简记 一分钟的你自己-读书简记 人生不设限-读书简记 暗时间-读书简记

利用UDP协议进行图像传输

2014年08月31日

写在前面


由于项目需要,自己实现了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;  
}  

以上。


版权声明:本文为博主原创文章,转载请注明出处 本文总阅读量    次