2013-07-15 89 views
1

我有以下基本的C++代碼,通過使用Linux上的套接字UDP傳輸文件。 問題是,並不是所有的數據包都被傳送(就像345kb中只有8個字節被接收到),我知道UDP是不可靠的,但是這是否與我的代碼或它只是因爲UDP的不可靠性有關?部分udp文件傳輸

客戶端

sockfd=socket(AF_INET,SOCK_DGRAM,0); 

bzero(&servaddr,sizeof(servaddr)); 
servaddr.sin_family = AF_INET; 
servaddr.sin_addr.s_addr=inet_addr("192.168.0.152"); 
servaddr.sin_port=htons(32000); 
ifstream myfile("345kb.doc", ios::in); 
int i=0; 
char* memblock; 
double size; 
if(myfile.is_open()) { 
    myfile.seekg(0,ios::end); 
    size=(double)myfile.tellg(); 
    memblock=new char[1024]; 
    myfile.seekg(0,ios::beg); 
    double filesize=size; 
    cout<<filesize; 
    int n; 
    int ab=(int)filesize%1024; 
    while(filesize>1024){ 
     myfile.read(memblock,1024); 
     cout<<"\nREAD:"<<strlen(memblock)<<"\n"<<"SENT:"; 
     n=sendto(sockfd,memblock,strlen(memblock),0,(struct sockaddr *)&servaddr,sizeof(servaddr)); 
     filesize=filesize-1024; 
     cout<<n<<"\n"; 
    } 
    myfile.read(memblock,1024); 
    n=sendto(sockfd,memblock,strlen(memblock),0,(struct sockaddr *)&servaddr,sizeof(servaddr)); 
    std::cout<<"HI"<<endl; 
} else { 
    printf("\nFILE NOT OPENED \n"); 
} 

SERVER端

int sockfd,n; 
struct sockaddr_in servaddr,cliaddr; 
socklen_t len; 
char mesg[1024]; 

sockfd=socket(AF_INET,SOCK_DGRAM,0); 

bzero(&servaddr,sizeof(servaddr)); 
servaddr.sin_family = AF_INET; 
servaddr.sin_addr.s_addr=htonl(INADDR_ANY); 
servaddr.sin_port=htons(32000); 
bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); 

//for (;;) 
//{ 
    ofstream myfile; 
    myfile.open("345kbsssss.doc",ios::out|ios::app); 
    if(myfile.is_open()) { 
     long i=0; 
     len = sizeof(cliaddr); 
     while((n = recvfrom(sockfd,mesg,1024,0,(struct sockaddr *)&cliaddr,&len))>0){ 
      std::cout<<"HI\n"; 
      //n=recvfrom(sockfd,mesg,256,0,(struct sockaddr *)&cliaddr,&len); 
      myfile.write(mesg,n); 
     } 
    } 
    else printf("\nFILE NOT CREATED\n"); 
//} 
+0

你可以嘗試改變傳輸類型爲TCP(如果這可能是服務器端,否則只使用'netcat'例如),看看你的文件是否正確傳遞。如果沒有,那是你的代碼有問題。 – Nbr44

+0

我與TCP得到它,但我只是想嘗試用UDP這只是爲了工作... – stranger

+0

此外服務器recvfrom的()荷蘭國際集團只有一次 – stranger

回答

3

兩者都是正確的:並不意味着

  • UDP用於文件傳輸,而不執行檢查,重新排序和重傳。而不是通過UDP實現所有這些,切換到TCP更好。除資源有限的嵌入式系統之外,這種情況極少。

  • 在您的代碼中,您使用strlen來獲取塊長度,因爲文件(很可能)是二進制文件,這會產生不正確的長度值,並且您不會傳輸整個文件數據。 strlen對零終止字符串進行操作,並且只計數到數據中的第一個0字節。

爲了得到更爲精確的結果,最簡單的方法是用min(1024,filesize)更換strlen(memblock)。這不是一個完美的解決方案,因爲它不檢查到底有多少字節被myfile.read讀取。

+0

感謝您的答覆,我想,現在 – stranger

+0

是啊,你是對的strlen是mistakeand我改變了它,但現在即時接收部分文件(如100KB出345KB),但再次服務器(接收器)卡在那一點,並沒有退出... – stranger