2016-08-04 63 views
0

我知道存在類似的問題,但是我還沒有發現它們適合我的問題。我有一個Android設備(API 15 - Android版本4.0.4)和一臺運行Arch Linux的Linux機器。這個想法是在服務器(C程序)和客戶端(Android應用程序)之間建立連接,以便我可以交換文件。另外,服務器支持並行連接並需要認證。 android應用程序必須創建3個到服務器的連接(使用3個不同的端口,這意味着3個AsyncTask-s運行多線程)。其中兩個用於並行後臺進程,1個用於實際文件傳輸。我創建了一個在Emulator(Android KitKat OS)上運行良好的代碼,但是在我自己的手機上進行測試時,它不起作用。我會發布我的代碼,如果可能的話,我希望得到您的一些建議。謝謝。使用TCP在Java(Android客戶端)和C(PC服務器 - Linux)之間進行文件傳輸

這是在Android設備上運行的代碼... BUFFSIZE 是1024,它是一個全局變量。 我試着將它設置爲很多值,並且它們都不適合我。文件大小是之前在代碼中設置的,總是正確的值,所以不要擔心:)

InputStream is = socket.getInputStream(); 
FileOutputStream fs = new FileOutputStream(target); 

int u; 
byte[] jj = new byte[BUFFSIZE]; 
long overall = 0, percent = 0; 

try { 

    while (overall < filesize && mRun) { 
      u = is.read(jj, 0, BUFFSIZE); 
      if (u == -1) break; 
      fs.write(jj, 0, u); 
      overall += u; 
      percent = overall*100/filesize; 
    } 

    fs.flush(); 
    fs.close(); 
    is.close(); 
    socket.close(); 

} catch (IOException ex) { 
    // There were no exceptions while testing 
    // There is some code here that deals with the UI 
    // which is not important 
} 

這是C代碼...

for (;;) 
    { 
     /* First read file in chunks of BUF_SIZE bytes */ 
     unsigned char buff[BUFFER]={0}; 
     int nread = fread(buffer,1,BUFFER, input); 
     printf("Bytes read %d \n", nread); 

     /* If read was success, send data. */ 
     if(nread > 0) 
     { 
      printf("Sending \n"); 
      write(sockfd, buffer, nread); 
     } 

     /* 
     * There is something tricky going on with read .. 
     * Either there was error, or we reached end of file. 
     */ 
     if (nread < BUFFER) 
     { 
      if (feof(input)) 
       printf("End of file\n"); 
      if (ferror(input)) 
       printf("Error reading\n"); 
      break; 
     } 
    } 

我已經測試此代碼很多時候,甚至使用telnet,它工作得很好。但我不確定Java代碼。

那麼,它爲什麼不工作?那麼,到目前爲止我所知道的是一些文件被損壞了。我們只是說,如果我傳輸一個大小爲4MB的mp3文件,那麼3.99將被髮送,而靜止的0.01將丟失在文件中間的某處,無緣無故!當你播放損壞的mp3時,你可以意識到某些部分(比如每10秒鐘)你就會「失控」。就像是有一小部分噪聲被跳過一樣。生成的文件比原始文件大約10 000個字節更短(但取決於實際文件大小..您總是會丟失一小部分文件,這意味着while循環永遠不會結束 - 下載過程永遠不會結束,因爲套接字被阻塞,並且客戶端最終等待更多從未接收到的字節)。我相信發生的事情是,從1024字節長的緩衝區中,有時使用大約1000字節,而不是完整的1024緩衝區大小,這導致24字節的丟失。我並不是說這些都是實際的數字,但是,這只是我腦海中發生的事情;我可能是錯誤的。我無法與你分享整個代碼,因爲它很長,所以我決定使用處理下載過程的函數。

回答

0

對於read方法來說,填充整個緩衝區是完全正確的。該方法返回讀取的字節數。你甚至該值賦值給一個變量:

u = is.read(jj, 0, BUFFSIZE); 

但你只檢查是否u是爲了找出什麼時候停止閱讀-1。從文檔:

The number of bytes actually read is returned as an integer. 

這意味着你的字節數組有1024個字節的最大長度,但並非所有這些都將在每個read填充。當然它不會,否則這隻會在你的輸入流包含1024字節的exakt倍數時才起作用。

另外:存在稱爲debugging的東西。可能很難檢查諸如mp3文件之類的二進制數據,因此請在傳輸文本文件時嘗試調試。

+0

是的,但爲什麼我的文件沒有收到呢?它適用於文本文件和調試時。它會因較大的文件而失敗。它不時跳過幾個字節。讓我們假裝這是整個文件:12345 ..它讀取123,然後是5 ..它跳過數字4,當它涉及到整個文件的結尾時,它會掛在那裏,因爲它期望讀取更多的字節還有一個是確切的 - 數字4)..這是大文件發生的事情,我無法弄清楚實際問題在哪裏。 – user3752782

相關問題