我有一个多线程 TCP 套接字监听器程序。我对特定字节数(128 字节和 4x 倍数)的数据进行阻塞读取,因此我的数据包大小为 128 字节、256 字节、384 字节和 512 字节。
我遇到问题,因为有时数据在套接字中变得困惑。例如:
应该读:
<header><data payload(padded with zeros to compensate size)><footer>
前-- ABCDdddddddddd0000000000WXYZ
我有时读到的内容:
例如-- ABCDdd00000000000000000dddddd00
然后下一个数据包看起来像
00000WXYZABCDddddd00000000000000000
所以我关闭了套接字,并且我们定义了发送回 2 或 3 个旧数据包的协议(protocol)以避免丢失。
我的问题是
1。为什么数据会变得困惑/困惑?
2。有办法避免吗?
这是我的读取数据的代码。
in = new DataInputStream(conn.getInputStream());
outStream = conn.getOutputStream();
while (m_bRunThread) {
// read incoming stream
in.readFully(rec_data_in_byte, 0, 128); //blocks until 128 bytes are read from the socket
{
//converting the read byte array into string
//finding out the size from a particular position,helps determine if any further reads are required or not.
//if the size is a multiple of 128 and the size is a multiple higher than 1 then more reads are required.
if ((Integer.parseInt(SIZE) % 128 == 0) && ((SIZE / 128) > 1)) {
for(int z = 1;z < lenSIZE;z++) {
in.readFully(rec_data_in_byte1, 0, 128);//changed from in.read(rec_data_in_byte1, 0, 128); as per suggestions
}
//extracting the data,validating and processing it
}
}
}
更新: 已实现 Peters 修复,但问题仍然存在。数据变得困惑。 添加几行额外代码,将字节数组转换为字符串。
byte[] REC_data=new byte[1024];
System.arraycopy(rec_data_in_byte1, 0, REC_data, 128*z, 128);
rec_data_string=MyClass2.getData(REC_data,0,Integer.parseInt(SIZE)-1,Integer.parseInt(SIZE));
getdata() 方法如下:
String msg = "";//the return String
int count = 1;
for (int i = 0; i < datasize; i++) {
if (i >= startindex) {
if (count <= lengthofpacket) {
msg += String.valueOf((char) (bytedata[i]));
count++;
}
}
}
return msg;
这是否可以成为争夺的原因?
P.S - 争夺的方式与之前一样。
最佳答案
当你这样做时
int lengthActuallyRead = in.read(rec_data_in_byte1, 0, 128);
您需要检查读取的长度。否则,它可能会读取 1 个字节,或者在本例中读取最多 128 个字节。请注意,实际读取的内容之后的任何字节都不会受到影响,因此它们可能是 0
或者它们可能是上一条消息留下的垃圾。
如果您期望 128 字节,您可以像以前一样使用 readFully
in.readFully(rec_data_in_byte, 0, 128);
注意:如果剩余金额少于 128,您可能需要执行此操作。
int remaining = size - sizeReadSoFar;
int length = in.read(rec_data_in_byte1, 0, remaining);
这可以防止您在阅读旧邮件时阅读下一条邮件的部分内容。
关于java - TCP 套接字数据变得困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36615608/