2015-01-21 115 views
1

我有一個應用程序,顯示來自手機的CCTV饋送。我成功地開發了iOS應用程序,現在我的客戶想讓我移植到Android。移植是好的,直到我被困在這部分代碼中。從TCP套接字(安卓)讀取JPEG字節

這部分代碼,我必須連接到TCP套接字服務器。連接時,我不必向服務器發送任何東西,相反,服務器會向我發送一個JPEG圖像。所以,連接後,我必須繼續閱讀,直到我收到JPEG結束標記(0xFF,0xD9),然後關閉連接。

我打算做的是

Socket s = new Socket("Server IP Addreess", SERVER_PORT); 
DataInputStream dis = new DataInputStream(socket.getInputStream()); 

ArrayList<Byte> bytes = new ArrayList<Byte>(); 
boolean err = false; 

while (true) { 
    byte b = dis.readByte(); 

    if (b == -1) { 
     err = true; 
     break; 
    }   

    bytes.add(b); 

    if ((bytes.get(bytes.size() - 1) == (byte) 0xFF) && 
     (bytes.get(bytes.size() - 2) == (byte) 0xD9)) { 
     break; 
    } 
} 

socket.close(); 

if (!err) { 
    // create bitmap from byte array and show in ImageView 
} 

但我不知道這是否正確。另一種解決方案,我想的是

Socket s = new Socket("Server IP Addreess", SERVER_PORT); 
BitmapFactory.decodeStream(s.getInputSteam()); 

但是,另外,我不知道如何關閉套接字時服務器發送0xFF的,0xD9。或者,BitmapFactory會爲我檢測標記並關閉套接字連接?

歡迎任何建議。謝謝!

P.S.當我提供iOS應用時,我沒有測試環境。所以,我必須開發並交付給他們測試(通過與應用程序一起玩)。如果它不工作,他們會告訴我糾正它,但我將無法訪問LogCat或其他有用的信息。這就像試圖在黑暗的房間裏縫一個按鈕,我不能打開燈。

:| |

編輯

關於該服務器的更多信息

  • 服務器將不會發送長度的文件的,所以,對於每個文件的字節數是未知的。
  • 我必須檢測0xFF,0xD9表明文件結束。
  • 問題是,我必須從我身邊終止套接字連接,服務器不會這樣做。
  • 我無法改變服務器的工作方式,這是我的客戶購買的硬件。

另外,我得到每個TCP連接一個圖像,我沒有得到單個TCP連接的多個圖像。

+0

他們不使用任何特殊協議?服務器在發送JPEG後關閉連接? – Dario 2015-01-21 08:05:25

+0

就是這樣,服務器不會從他們那邊終止連接,我必須自己做。這是一個不好的硬件設計。 – 2015-01-21 08:17:28

回答

2

這是一個壞主意,只是尋找一些神奇的字節來確定數據的結束。雖然這些魔術字節應該在文件末尾,但它們也可能發生在數據內部。

更好的辦法是將數據加上長度前綴,或者對每個jpeg文件使用單獨的TCP連接,直到連接結束(直到您沒有獲得更多數據)爲止。如果這不可行,則必須進行更高級的解析,請參閱Detect Eof for JPG images

+0

感謝您的稱讚。事情是,我知道肯定是1.)服務器將始終發送0xFF,0xD9表示文件2的結尾。)服務器會一次發送一個圖像(因此,0xFF,0xD9之後沒有任何內容)3.)但是,我必須關閉來自我身邊的套接字連接,服務器不會這樣做。 (所以,是的,我爲每個TCP連接獲取一個圖像,而不是多個圖像) – 2015-01-21 08:09:16

+0

是的,服務器會用FFD9指示文件末尾,但不能確定FFD9不在jpeg文件本身內。所以你需要有一個更高級的檢測算法,如我已經鏈接的文章中所述。 – 2015-01-21 08:16:14

+0

我現在明白了你的觀點。 – 2015-01-21 08:20:41