我爲客戶端 - 服務器應用程序使用Java套接字。有時客戶端需要發送一個字節數組(使用byteArrayOutputStream),有時它應該發送一個自定義Java對象。如何從服務器端的輸入流中讀取信息並確定流中的內容,以便我可以正確處理該信息?Java套接字 - 如何確定服務器端的數據類型?
回答
首先將數據讀取到服務器上的字節數組中。編寫你自己的解析例程,只不過是識別字節數組中的內容。
第二步根據第一步的識別執行完整的對象解析。如果解析需要傳遞一個輸入流,那麼您總是可以將您在第一步中讀取的字節數組放入一個新的ByteArrayInputStream實例中。
你可以做什麼,將預先發送任何數據與一個整數,用於確定類型。
這樣,您可以讀取前4個字節,然後確定它是什麼類型的數據。
總的來說,我不相信Java中有一個功能可以讓你做到這一點。
取而代之的是,考慮發送更多的信息以及解釋接下來會發生什麼類型的每條消息。例如,你可能用一個整數前綴你的消息,這樣每次你收到一條消息時,你會讀取前4個字節(一個整數是4個字節)並解釋它的值(例如1 = byte數組,2 =自定義Java對象,3 =另一個自定義Java對象,...)。
您也可以考慮添加一個包含消息大小的整數,以便知道當前消息何時結束並且下一條消息何時開始。
您需要定義一個協議來指出後面的數據類型。例如,您可以使用字符串或枚舉值開始每次傳輸。服務器首先讀取這個數據,然後根據'header'值讀取以下數據。
通常這是通過在身體前面發送一個包含身體信息的「標題」來完成的。看看例如HTTP protocol。 HTTP流存在一個由雙換行符與主體分離的頭部。標題依次存在name: value
格式的幾個字段,每個字段由一個換行符分隔。在這種特殊情況下,你可以在HTTP中使用Content-Type
頭來標識正文的數據類型。
由於Java和TCP/IP沒有爲此提供標準功能,因此您需要指定並記錄您要通過線路詳細發送的格式,以便另一方知道如何處理流。您當然也可以獲取標準規格。例如。 HTTP或FTP。
有多種方法可以處理這個問題。
一個是對象序列化,它使用Java的Object(In | Out)putStream發送它。當知道何時從流中讀取對象時,遇到一個小問題。另一個是編組和解組XML。使用更多的流量,但更容易調試和運行。它有助於爲此提供一個良好記錄的XML模式。這裏的優點是可以使用現有的XML庫。
如果需要,您可以嘗試使用自定義格式,但它可能最終只是一個草率的,不太冗長的XML版本。
我會因此而被要求過度殺毒,但除非您認真需要此協議是經濟的,否則您可能會考慮編組數據。我的意思是,在不偷看數據的情況下,通常不能區分是字節數組和其他東西之間的區別,因爲可以想象將所有數據都表示爲字節數組。
您可以非常輕鬆地使用JAXB將數據收集到XML或從XML收集數據。而JAXB甚至會將字節數組對象轉換爲十六進制字符串或Base64。
這是一個巧妙的技巧..但我需要這個儘可能經濟... – markovuksanovic 2010-05-07 18:53:11
我認爲最簡單的方法是使用一個對象,其中包含您將隨其類型信息一起發送的數據。然後你可以發送這個對象,根據這個對象的數據類型屬性,你可以提取數據。
- 1. 套接字java客戶端服務器
- 2. Java套接字客戶端/服務器
- 3. Java套接字從客戶端發送數據到服務器
- 4. C套接字服務器,Java套接字客戶端:阻塞!
- 5. Python套接字客戶端到Java套接字服務器
- 6. 套接字IO |如何獲得服務器端的客戶端傳輸類型?
- 7. Java服務器套接字
- 8. 服務器端formdata的數據類型
- 9. 客戶端套接字接受的數據與服務器套接字不同
- 10. 如何確定MongoDB服務器類型
- 11. 服務器不接收來自多個客戶端(java套接字)的數據
- 12. Java如何確定進入UDP服務器的數據類型? XML Binary
- 13. Java套接字 - 關閉到服務器套接字的telnet客戶端連接
- 14. java套接字服務器和套接字客戶端之間的連接
- 15. 多端的Netty套接字服務器
- 16. 接受客戶端的Java服務器套接字
- 17. ExtJS遠程過濾 - 確定服務器端的過濾器數據類型
- 18. Java Socket服務器沒有從客戶端套接字接收數據
- 19. 如何在java服務器套接字中處理不同的響應類型
- 20. 如何運行一個java類作爲套接字服務器
- 21. Java套接字。服務器端與客戶端通訊
- 22. Java客戶端/服務器套接字端口分配
- 23. 套接字編程數據服務器
- 24. 在Java服務器上接收ios套接字數據
- 25. 從Java服務器套接字接收C#客戶端套接字中的數據時出錯
- 26. Java雙向套接字連接(服務器/客戶端)
- 27. 無法連接Java套接字服務器和客戶端
- 28. Java客戶端/ Ruby服務器套接字連接
- 29. Android客戶端PC服務器java套接字連接失敗
- 30. PHP套接字服務器/客戶端
如果你打算做一個消息開始/結束標誌,這對組成一個轉義協議特別有用,這樣如果你變得不同步,你可以查找消息開始標誌。如果消息開始字節出現在代碼中的任何位置,則將其轉換爲兩字節轉義序列。您還可以逃避轉義字符本身以及您想避免的任何其他字節(^ S和^ Q,例如,通過RS-232使用時)。 – nsayer 2010-05-07 18:51:25
我不會建議開始/結束標誌,因爲在序列化Java類時,因爲在嘗試序列化Java類時可能會發現任何字符(^ S,^ Q,\ 0等)。我建議包括消息的長度和消息的類型。雖然,海報可能已經知道這是基於Java對象的類型(也許對象將始終具有完全相同的字段)。 – 2010-05-07 19:18:23
你做的轉義是爲了確保你的協議完全是二進制安全的,儘管你有特殊的開始/結束標記字節(也許你想完全避免的字節)。如果兩個端點變得不同步,則長度字節不會幫助您恢復,但是,不必承認,您可能不需要擔心TCP連接。 – nsayer 2010-05-07 21:04:22