zoukankan      html  css  js  c++  java
  • 基于UDT connect连接通信以及文件传输--服务端

    网上与UDT相关的资料不多,与UDT相关的源码例子更少。最近在接触UDT,也是因为缺少相关的资料,导致学习起来甚感痛苦。下面将我自己这两天弄出来的代码贴出来,希望对在寻找相关资料的童鞋有一定的帮助。与服务端相对应的客户端在另一篇博文中

    [cpp] view plain copy
     
    1.   

            SERVER端

    [cpp] view plain copy
     
    1. #include <iostream>  
    2. #include "udt.h"  
    3. #include <io.h>  
    4.   
    5. #pragma comment(lib,"ws2_32.lib")  
    6.   
    7. using namespace std;  
    8.   
    9. #define MAXLEN 4096  
    10.   
    11. int main(int argc,char *argv[])  
    12.  {     
    13.      if ((argc != 4))  
    14.      {  
    15.         cout<<"Use: appserver.exe server_port client_ip client_port"<<endl;  
    16.         return 0;  
    17.      }  
    18.   
    19.      //startup  
    20.     //这里是对UDT的启动记性初始化操作  
    21.      if (UDT::ERROR == UDT::startup())  
    22.      {  
    23.          cout<<"startup: "<<UDT::getlasterror().getErrorMessage()<<endl;  
    24.      }else{  
    25.         cout<<"startup suc..."<<endl;  
    26.      }  
    27.   
    28.      //socket  
    29.     //像声明一个普通的socket一样声明一个UDTSOCKET  
    30.      UDTSOCKET serv = UDT::socket(AF_INET, SOCK_DGRAM, 0);  
    31.      if (UDT::ERROR == serv)  
    32.     {  
    33.         cout<<"socket: "<<UDT::getlasterror().getErrorMessage()<<endl;  
    34.     }else{  
    35.         cout<<"client suc..."<<endl;  
    36.     }  
    37.   
    38.      //声明udp socket,这里是udp的哈,不是udt  
    39.      int sersocket = socket(AF_INET,SOCK_DGRAM,0);  
    40.      if (SOCKET_ERROR == sersocket)  
    41.     {  
    42.         cout<<"udp socket error!"<<endl;  
    43.     }else{  
    44.         cout<<"clientsocket suc..."<<endl;  
    45.     }  
    46.   
    47.     //为了能够在局域网中直接进行处理,先默认设置两个  
    48.      sockaddr_in my_addr,client_addr;  
    49.      my_addr.sin_family = AF_INET;  
    50.      my_addr.sin_port = htons(atoi(argv[1]));  
    51.      my_addr.sin_addr.s_addr = INADDR_ANY;  
    52.      memset(&(my_addr.sin_zero), '', 8);  
    53.      bind(sersocket,(struct sockaddr*)&my_addr,sizeof(my_addr));  
    54.   
    55.      client_addr.sin_family = AF_INET;  
    56.      client_addr.sin_port = htons(atoi(argv[3]));  
    57.      client_addr.sin_addr.s_addr = inet_addr(argv[2]);  
    58.      //client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  
    59.      memset(&(client_addr.sin_zero), '', 8);  
    60.   
    61.      int mss = 1052;//最大传输单位  
    62.      //设置收发缓冲区大小 接收限时  和地址重用  
    63.     if(   !( UDT::ERROR != (UDT::setsockopt(serv, 0, UDT_SNDBUF, new int(32000), sizeof(int)))  
    64.         && UDT::ERROR != (UDT::setsockopt(serv, 0, UDP_RCVBUF, new int(32000), sizeof(int)))  
    65.         && UDT::ERROR != (UDT::setsockopt(serv,0,UDT_REUSEADDR,new int(1),sizeof(int)))  
    66.         && UDT::ERROR != (UDT::setsockopt(serv, 0, UDT_RENDEZVOUS, new bool(true), sizeof(bool))))  
    67.         && UDT::ERROR != (UDT::setsockopt(serv, 0, UDT_MSS, &mss, sizeof(int)) ))  
    68.     {  
    69.         cout<<"udt socket: "<<UDT::getlasterror().getErrorMessage()<<endl;  
    70.         UDT::close(serv);  
    71.         return 0;  
    72.     }  
    73.     //这里是直接将udp的接口绑定在udt的接口之上,如果不这样做的话是没法使用UDT中的SOCK_DGRAM的  
    74.      if (UDT::ERROR == UDT::bind2(serv,sersocket))  
    75.      {  
    76.         cout<<"udt bind2:"<<UDT::getlasterror().getErrorMessage()<<endl;  
    77.         return 0;  
    78.      }else{  
    79.         cout<<"bind2 suc"<<endl;  
    80.      }  
    81.     //这里也是关键部分,与client端对应的connect操作,就是相互之间的打洞处理  
    82.      if (UDT::ERROR == UDT::connect(serv, (sockaddr*)&client_addr, sizeof(client_addr)))  
    83.      {  
    84.        cout << "connect: " << UDT::getlasterror().getErrorMessage();  
    85.        UDT::close(serv);  
    86.        return 0;  
    87.      }else{  
    88.         cout<<"connetc suc"<<endl;  
    89.      }  
    90.     //这里已经可以正常接收了,接收从client发过来的filename,目的是用于本地的文件创建  
    91.      char filename[100];  
    92.      if (UDT::ERROR == UDT::recvmsg(serv, filename, 100))  
    93.      {  
    94.        cout << "recv:" << UDT::getlasterror().getErrorMessage() << endl;  
    95.        return 0;  
    96.      }  
    97.      cout <<"filename: "<< filename <<endl;  
    98.   
    99.     //使用FILE进行文件操作,关于文件的相关操作这里不详述了,实在不懂的可以留言  
    100.      FILE *fp;  
    101.      char localfile[100];  
    102.      memset(localfile,0,sizeof(localfile));  
    103.      strcpy(localfile,"d:\");  
    104.      strcat(localfile,filename);  
    105.      if((fp = fopen(localfile,"w+"))==NULL)  
    106.      {  
    107.         cout<<filename<<" open failure!"<<endl;  
    108.         return 0;  
    109.      }  
    110.      fclose(fp);  
    111.      fp = fopen(localfile,"wb");  
    112.   
    113.      char data[MAXLEN];  
    114.      int len=0,package=0,filelen=0;  
    115.      UDT::TRACEINFO trace;  
    116.      UDT::perfmon(serv,&trace);    
    117.      while(1)  
    118.      {  
    119.         //前面部分打开文件后,这里就是循环接收文件并保存  
    120.         memset(data,0,sizeof(data));  
    121.         len = UDT::recvmsg(serv, data, MAXLEN);  
    122.         filelen += len;  
    123.         //cout<<"filelen = "<<filelen<<endl;  
    124.         if (strncmp("quit",data,4)==0)  
    125.         {  
    126.             cout<<data<<endl;  
    127.             fclose(fp);  
    128.             break;  
    129.         }else  
    130.         {  
    131.             package ++;//record recv all the packages  
    132.         }  
    133.         fwrite(data,len,1,fp);        
    134.      }  
    135.      fclose(fp);  
    136.      fp = fopen(localfile,"rb");  
    137.      fseek(fp,0,SEEK_END);//move to the end  
    138.      filelen = ftell(fp)  
    139.      fseek(fp,0,SEEK_SET);  
    140.      cout<<"filesize = "<<filelen<<endl;  
    141.      UDT::perfmon(serv,&trace);  
    142.      cout << "speed = " << trace.mbpsRecvRate << "Mbits/sec" << endl;  
    143.      cout<<"recv all the packages: "<<package<<endl;  
    144.   
    145.      fclose(fp);  
    146.      UDT::close(serv);  
    147.      UDT::cleanup();  
    148.   
    149.      return 1;  
    150.  }   


     
     
    运行效果截图:
     
    注:要想运行这两个程序直接把源代码复制下来,然后去运行肯定是不行的,这个是需要UDT其它类库的支持的,也就是说,需要你将UDT的源代码文件拷贝进你的项目文件中才行。源代码下载地址:http://blog.csdn.net/pingd/article/details/14519881
    简单截图如下:
  • 相关阅读:
    Linux iptables常用命令
    Docker数据卷
    Ubuntu14.04下安装docker 1.9
    初识微服务
    初识微服务
    无状态服务(stateless service)
    git生成ssh key 避免每次push都要输入账号密码
    fiddler和xampp安装成功后,网站打不开的原因
    ajax设置自定义请求头信息
    ajax跨域之设置Access-Control-Allow-Origin
  • 原文地址:https://www.cnblogs.com/lidabo/p/6846647.html
Copyright © 2011-2022 走看看