2013-07-06 72 views
0

我有我希望的一個問題是一個錯誤,因爲我有點新來的Linux C.ç3G文件傳輸客戶端/服務器的Linux

我有一個服務器,發送文件到客戶端。該代碼完全適用於有線連接,每次都能100%成功。但是,當我嘗試通過-65dB(強)的3G USB連接運行相同的代碼時,客戶端通常只會接收文件的前1或2千字節。 (請原諒的語法錯誤,不會讓我的空間正常)

 // CLIENT CODE 

     char* fs_name = "/target/to/send"; 
     char sdbuf[LENGTH]; // Send buffer, LENGTH == 512 
     printf("Sending %s to the Client... \n", fs_name); 
     FILE *fs = fopen(fs_name, "r"); 
     if(fs == NULL) 
     { 
      fprintf(stderr, "ERROR: File %s not found on server. (errno = %d)\n", fs_name, errno); 
      exit(1); 
     } 

     bzero(sdbuf, LENGTH); 
     int fs_block_sz; 
     while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs))>0) 
     { 
      if(send(client, sdbuf, fs_block_sz, 0) < 0) 
      { 
       fprintf(stderr, "ERROR: Failed to send file %s. (errno = %d)\n", fs_name, errno); 
       exit(1); 
      } 
      bzero(sdbuf, LENGTH); 
     } 
     printf("File send Success\n"); 



      // SERVER CODE 

     char* fr_name = "/home/file/to/save"; 

     FILE *fr = fopen(fr_name, "a"); 

     if(fr == NULL) 

      printf("File %s Cannot be opened.\n", fr_name); 

     else 
     { 
       // zero out bytes 
      bzero(revbuf, LENGTH); 

      int fr_block_sz = 0; 

      while((fr_block_sz = recv(sd, revbuf, LENGTH, 0)) > 0) //LENGTH == 512 
      { 
      int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr); 

       if(write_sz < fr_block_sz) 
      { 
        error("File write failed.\n"); 
       } 
      bzero(revbuf, LENGTH); 
      if (fr_block_sz == 0 || fr_block_sz != 512) 
      { 
      break; 
      } 
     } 

       // error checking 
     if(fr_block_sz < 0) 
       { 
     if (errno == EAGAIN) 
     { 
      printf("recv() timed out.\n"); 
     } 
     else 
     { 
      fprintf(stderr, "recv() failed due to errno = %d\n", errno); 
     } 


      fclose(fr); 

如果有任何人可以對我在做什麼錯了,我會最欣賞一些啓發。謝謝閱讀。

編輯:服務器是Ubuntu 10.04,客戶端是Arch Linux ARM,發送的文件類型是ARM二進制文件。

+0

爲什麼客戶端,有什麼回報RECV在週期的退出?如果rect返回<0打印fprintf(stderr,「recv返回錯誤:%s \ n」,sterror(errno))? – fghj

+0

如果我正確理解你的意思,客戶端不會收到錯誤。客戶端簡單地保存文件,就好像它是完整的東西,並沒有提供錯誤信息,服務器也沒有。然後我必須手動調整該文件的大小以查找xfer失敗。它有時可以工作,但可能有15%的時間。也許我需要以1000字節塊發送文件,然後在客戶端重新組裝它或其他東西?不幸的是,我注意到3G與電線有點不同。 – 4r4r4r

+0

你談論某種魔術。如果您有TCP連接,並且從一邊發送100MB文件塊在另一邊您收到或100MB或連接斷開。可能你使用UDP? – fghj

回答

0

我認爲你的主要問題是在你的代碼標記爲服務器,但真正看起來是客戶端。你假設recv將在每個recv上獲得全部512個字節,但事實並非如此 - 你可以並且會得到短的讀取。如果你沒有完全讀取LENGTH(即512),稍微低於讀取循環。這就解釋了爲什麼你的pgm在幾千字節之後退出。

while ((fr_block_sz = recv(sd, revbuf, LENGTH, 0)) > 0) //LENGTH == 512 
    { 
     int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr); 

     if (write_sz < fr_block_sz) 
     { 
      error("File write failed.\n"); 
     } 

     bzero(revbuf, LENGTH); 

     if (fr_block_sz == 0 || fr_block_sz != 512) 
     { 
      break; 
     } 

    } 

你想要更多的東西是這樣的:(根據您的代碼服務器)僅收到1000字節

while ((fr_block_sz = recv(sd, revbuf, LENGTH, 0)) > 0) //LENGTH == 512 
    { 
     if (fr_block_sz < 0) 
      if (errno == EAGAIN) 
       continue; 
      else 
       error; 

     if (fr_block_sz == 0) 
      break; //done 

     int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr); 

     if (write_sz < fr_block_sz) 
     { 
      error("File write failed.\n"); 
     } 

     bzero(revbuf, LENGTH); 
    } 
+0

謝謝鴨子,但我不明白。我有服務器代碼與客戶端混淆,我的服務器真的是客戶端,你發佈的代碼是我的服務器應該看起來像什麼樣的客戶端? – 4r4r4r

+0

服務器/客戶端/無論如何。這在這裏並不重要。以上代碼直接來自您發佈的內容。我會發布一些我認爲應該解決您的主要問題的僞代碼。 – Duck

+0

Thanks Duck,我能夠根據您的僞代碼(在服務器保持不變的情況下)在客戶端進行這些更改,並且使得我的成功率爲5/7,其他傳輸成功率達到了4K字節。 2次失敗的嘗試可能是由於3G連接。奇怪它如何在電線上正常工作。我想知道3G編程技術是否與傳統的有線編程不同。 – 4r4r4r

相關問題