2012-08-22 31 views
0

我已經實現了一個Android應用程序,該應用程序使用SP相機拍攝照片並通過套接字將其發送到服務器。通過套接字發送的圖像流 - 服務器死鎖問題

我用下面(JAVA)的代碼讀取本地存儲的圖像文件,並在連續的塊在插槽發送:

FileInputStream fileInputStream = new FileInputStream("my_image_file_path"); 

int nRead; 
byte[] data = new byte[16384]; 

try { 
    while((nRead = fileInputStream.read(data, 0, data.length)) != -1){ 
     networkOutputStream.write(data, 0, nRead); 
    } 

} catch(IOException e){ 
    e.printStackTrace(); 
} 
fileInputStream.close(); 

而下面的(C/C++),代碼讀取它並將其存儲在服務器上:

char newbuffer[MAX_BUF_SIZE]; 
int checkOperation; 

ofstream outfile("image_file_path".c_str(), ofstream::binary); 

do{ 
    checkOperation = read(clientSocketDescriptor, newbuffer, sizeof(newbuffer)); 

    if(checkOperation < 0){ 

     cout << "Error in recv() function, received bytes = " << checkOperation << endl; 
     exit(1); 
    }else if (checkOperation != 0){ 

     /* 
     * some data was read 
     */ 
     cout << endl << "READ Bytes: " << checkOperation << endl; 
     outfile.write(newbuffer, checkOperation); 

     /* 
     * emptying buffer for new incoming data 
     */ 
     for(int i = 0; i < sizeof(newbuffer); i++){ 
      newbuffer[i] = 0; 
     } 
    } 
}while(checkOperation =! 0); 

outfile.close(); 

Android客戶端應用程序似乎正確地寫在插座的所有字節,併成功地從while循環退出。

但是,服務器代碼卡在while循環的最後一次迭代中,並且無法繼續執行。

  • 爲什麼服務器不能讀取EOF
  • 我的代碼發送圖像或閱讀它不正確?

在此先感謝您提供任何幫助,因爲我真的被卡住了!

+1

因爲你不發送EOF ... – njzk2

回答

3

你沒有關閉networkOutputStream,所以C++代碼不知道你已經完成了。

要麼你需要關閉輸出流 - 如果你不需要發送更多數據,顯然你只需要關閉輸出流;或者你需要在協議中包含一些元數據,以便在開始寫之前指明還有多少數據,或者之後包含什麼作爲「完成」指標。通常我更喜歡長度前綴 - 如果「完成」指標自然出現在數據中,那麼它比不必擔心轉義更簡單。

一箇中途的房子會反覆說「這裏有一大塊數據長度爲X」,然後是「我完成了,沒有更多的塊」消息(可能是「這是一個數據長度爲0的塊」例)。這樣你事先不需要知道總長度。

+0

我沒有關閉'networkOutputStream'因爲我需要發送一些其他數據後的圖像(一些文本文件與圖像的描述)。在你看來,對於我的特殊用例,最好的過程是什麼?你需要的時間...... – Matteo

+0

而且,在使用'networkOutputStream.flush()'方法發送圖像之後刷新流可以解決問題? – Matteo

+0

@Matteo:不,只是沖洗不會有幫助 - 因爲C++代碼仍然不知道你已經完成了。如果您需要發送其他信息,我會將每個數據長度作爲前綴(即圖像的長度前綴,文本信息的另一長度等)。如果在開始編寫代碼之前找出完整的長度是非常棘手的,那麼可以選擇分塊解決方案。 –