簡體   English   中英

套接字上的InputStream讀取零

[英]InputStream on socket reads zeros

我嘗試在服務器端收到原始二進制數據包。 我可以控制數據格式,並指定數據包的前4個字節來描述數據包的長度(它是將int值轉換為byte []並返回的int值)。 這樣效果很好,我得到了正確的數字(我也可以監視和檢查客戶端)。 這是代碼:

is = connectionSocket.getInputStream();
byte[] intArray = new byte[4];
//read the 4-byte int value to array
is.read(intArray, 0, 4);
int packetLength = ByteBuffer.wrap(intArray).getInt();

然后,我想將包(不包括長度標題)讀取到自定義適合字節數組中:

byte[] packet = new byte[packetLength];//make a buffer ready
is.read(packet, 0, packetLength);//read the whole packet to array

如果發送的byte []的長度為1444或更短,則一切正常。 但是超出此限制的數據包將無法正確接收。 數據包數組的開頭將正確填充數據,但是在限制之后,像這樣直到結尾都只有零

Positon: ...|1440|1441|1442|1443|1444|1445|1446|1447|.........|packetLength-1
Data:    ...| 59 |-73 | 125| -3 |  0 |  0 |  0 |  0 |..zeros..| 0

從我還是13歲的想上網的調音大師開始,我仍然記得,Windows機器上有大約1500字節的標准MTU(最大傳輸單位)。 的確,我的接收網絡適配器的MTU為1500。可疑地接近1444,因此我增加了MTU,但可惜沒有結果。 Java不應讓我這么低級的東西困擾我,但是也許這不是巧合。 順便說一句,客戶端是Android智能手機,接收器是Windows 7計算機。

是否有人有其他想法甚至更好的解決方案?

您將忽略read(),返回的計數read(),並假定它已填充緩沖區。 它沒有義務這樣做。 請參閱Javadoc。

正確執行操作的簡單方法是使用DataInputStream.readInt(),然后使用readFully().

注意:與您的評論相反,僅添加int size =完全沒有效果。 這是不可能的。 出於其他一些原因,時間發生了變化,因此真正到達了四個字節。

最終,我了解了自己的類似種族狀況的本質,但感謝您的幫助和澄清。 當我注意到設置調試停止可以解決問題時,我注意到了這一點,這使緩沖區有時間完成其工作。 再次感謝,使用DataInputStream更好地編寫了代碼。 這是我(希望)的最終解決方案:

DataInputStream dis = new DataInputStream(connectionSocket.getInputStream());
int packetLength = dis.readInt();
byte[] packet = new byte[packetLength];//make a buffer ready       
dis.readFully(packet);//read full packet to buffer

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM