天天看點

基于UDT connect連接配接通信以及檔案傳輸--服務端

網上與UDT相關的資料不多,與UDT相關的源碼例子更少。最近在接觸UDT,也是因為缺少相關的資料,導緻學習起來甚感痛苦。下面将我自己這兩天弄出來的代碼貼出來,希望對在尋找相關資料的童鞋有一定的幫助。與服務端相對應的用戶端在另一篇博文中

#include <iostream>  

#include "udt.h"  

#include <io.h>  

#pragma comment(lib,"ws2_32.lib")  

using namespace std;  

#define MAXLEN 4096  

int main(int argc,char *argv[])  

 {     

     if ((argc != 4))  

     {  

        cout<<"Use: appserver.exe server_port client_ip client_port"<<endl;  

        return 0;  

     }  

     //startup  

    //這裡是對UDT的啟動記性初始化操作  

     if (UDT::ERROR == UDT::startup())  

         cout<<"startup: "<<UDT::getlasterror().getErrorMessage()<<endl;  

     }else{  

        cout<<"startup suc..."<<endl;  

     //socket  

    //像聲明一個普通的socket一樣聲明一個UDTSOCKET  

     UDTSOCKET serv = UDT::socket(AF_INET, SOCK_DGRAM, 0);  

     if (UDT::ERROR == serv)  

    {  

        cout<<"socket: "<<UDT::getlasterror().getErrorMessage()<<endl;  

    }else{  

        cout<<"client suc..."<<endl;  

    }  

     //聲明udp socket,這裡是udp的哈,不是udt  

     int sersocket = socket(AF_INET,SOCK_DGRAM,0);  

     if (SOCKET_ERROR == sersocket)  

        cout<<"udp socket error!"<<endl;  

        cout<<"clientsocket suc..."<<endl;  

    //為了能夠在區域網路中直接進行處理,先預設設定兩個  

     sockaddr_in my_addr,client_addr;  

     my_addr.sin_family = AF_INET;  

     my_addr.sin_port = htons(atoi(argv[1]));  

     my_addr.sin_addr.s_addr = INADDR_ANY;  

     memset(&(my_addr.sin_zero), '\0', 8);  

     bind(sersocket,(struct sockaddr*)&my_addr,sizeof(my_addr));  

     client_addr.sin_family = AF_INET;  

     client_addr.sin_port = htons(atoi(argv[3]));  

     client_addr.sin_addr.s_addr = inet_addr(argv[2]);  

     //client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  

     memset(&(client_addr.sin_zero), '\0', 8);  

     int mss = 1052;//最大傳輸機關  

     //設定收發緩沖區大小 接收限時  和位址重用  

    if(   !( UDT::ERROR != (UDT::setsockopt(serv, 0, UDT_SNDBUF, new int(32000), sizeof(int)))  

        && UDT::ERROR != (UDT::setsockopt(serv, 0, UDP_RCVBUF, new int(32000), sizeof(int)))  

        && UDT::ERROR != (UDT::setsockopt(serv,0,UDT_REUSEADDR,new int(1),sizeof(int)))  

        && UDT::ERROR != (UDT::setsockopt(serv, 0, UDT_RENDEZVOUS, new bool(true), sizeof(bool))))  

        && UDT::ERROR != (UDT::setsockopt(serv, 0, UDT_MSS, &mss, sizeof(int)) ))  

        cout<<"udt socket: "<<UDT::getlasterror().getErrorMessage()<<endl;  

        UDT::close(serv);  

    //這裡是直接将udp的接口綁定在udt的接口之上,如果不這樣做的話是沒法使用UDT中的SOCK_DGRAM的  

     if (UDT::ERROR == UDT::bind2(serv,sersocket))  

        cout<<"udt bind2:"<<UDT::getlasterror().getErrorMessage()<<endl;  

        cout<<"bind2 suc"<<endl;  

    //這裡也是關鍵部分,與client端對應的connect操作,就是互相之間的打洞處理  

     if (UDT::ERROR == UDT::connect(serv, (sockaddr*)&client_addr, sizeof(client_addr)))  

       cout << "connect: " << UDT::getlasterror().getErrorMessage();  

       UDT::close(serv);  

       return 0;  

        cout<<"connetc suc"<<endl;  

    //這裡已經可以正常接收了,接收從client發過來的filename,目的是用于本地的檔案建立  

     char filename[100];  

     if (UDT::ERROR == UDT::recvmsg(serv, filename, 100))  

       cout << "recv:" << UDT::getlasterror().getErrorMessage() << endl;  

     cout <<"filename: "<< filename <<endl;  

    //使用FILE進行檔案操作,關于檔案的相關操作這裡不詳述了,實在不懂的可以留言  

     FILE *fp;  

     char localfile[100];  

     memset(localfile,0,sizeof(localfile));  

     strcpy(localfile,"d:\\");  

     strcat(localfile,filename);  

     if((fp = fopen(localfile,"w+"))==NULL)  

        cout<<filename<<" open failure!"<<endl;  

     fclose(fp);  

     fp = fopen(localfile,"wb");  

     char data[MAXLEN];  

     int len=0,package=0,filelen=0;  

     UDT::TRACEINFO trace;  

     UDT::perfmon(serv,&trace);    

     while(1)  

        //前面部分打開檔案後,這裡就是循環接收檔案并儲存  

        memset(data,0,sizeof(data));  

        len = UDT::recvmsg(serv, data, MAXLEN);  

        filelen += len;  

        //cout<<"filelen = "<<filelen<<endl;  

        if (strncmp("quit",data,4)==0)  

        {  

            cout<<data<<endl;  

            fclose(fp);  

            break;  

        }else  

            package ++;//record recv all the packages  

        }  

        fwrite(data,len,1,fp);        

     fp = fopen(localfile,"rb");  

     fseek(fp,0,SEEK_END);//move to the end  

     filelen = ftell(fp)  

     fseek(fp,0,SEEK_SET);  

     cout<<"filesize = "<<filelen<<endl;  

     UDT::perfmon(serv,&trace);  

     cout << "speed = " << trace.mbpsRecvRate << "Mbits/sec" << endl;  

     cout<<"recv all the packages: "<<package<<endl;  

     UDT::close(serv);  

     UDT::cleanup();  

     return 1;  

 }   

運作效果截圖:

基于UDT connect連接配接通信以及檔案傳輸--服務端

簡單截圖如下:

基于UDT connect連接配接通信以及檔案傳輸--服務端

繼續閱讀