繁体   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