[英]Java Socket InputStream reads data but return in the wrong order
[英]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.