[英]How to receive the same messages sent via TCP socket?
我在Java中有一個TCP套接字客戶端-服務器程序。
從客戶端,我每秒鍾發送幾次二進制消息(來自byte []的二進制數據)。
從服務器,我想以相同的順序和大小讀取這些消息。
問題是服務器顯然並不總是讀取相同大小的消息。 似乎將它們“分組”。 例如:
客戶端發送:12個字節-12個字節-12個字節-12個字節-15個字節-15個字節
服務器接收:12個字節-48個字節-15個字節-15個字節
我該如何預防?
現在,我的代碼是:
客戶:
(initialization)
mySocket = new Socket(direccion, puerto);
mySocket.setTcpNoDelay(true);
BufferedOutputStream os = new BufferedOutputStream( mySocket.getOutputStream() );
(sending)
os.write( bytes );
os.flush();
服務器
(initialization)
serverSocket = new ServerSocket(12321);
Socket con = serverSocket.accept();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
(receiving)
char[] msg = new char[1024];
String mensaje;
int nbytes;
nbytes = reader.read(msg);
我無法手動分離分組的消息,因為它們是二進制消息,並且該模塊無法“理解”它們。
因此,問題是:如何確保讀者單獨獲得消息?
謝謝
您正在使用數據流來傳輸消息。 從概念上講,流只是字節序列-沒有消息 。 您需要自己將流分割為消息/數據包。 您甚至可以在當前代碼中通過一次調用獲得消息的一部分,而通過下一次調用獲得消息的一部分。 現在,您的代碼從根本上來說是有缺陷的。
引入一種機制,該機制可以清楚地檢測消息的開始/結束位置。 一種簡單的方法是將每個數據包的長度編碼為每個數據包的第一個字節。 然后,接收器可以先讀取長度,然后再知道該包中有多少個后續字節。
另一種方法是具有一個消息分隔符符號,該符號指示當前數據包的結束。 由於您正在發送二進制數據,因此這將要求數據包不包含所有可能的字節值,或者您需要以不使用所有可能的字節值的方式對數據包進行編碼。
具有長度的方法更易於實現,而結束符號方法對於您可以輕松引入新符號的方案(例如,如果整個數據包都經過霍夫曼編碼)很有用。
TCP連接傳輸流的本質是TCP。
您的選擇是
手動分隔消息,例如,在每條消息之前添加一個長度字段。 這需要更改協議。
使用不同於TCP的協議。 要么是UDP(但是卻失去了可靠性),要么是STCP(我不確定Java是否能夠做到這一點)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.