Java TCP套接字数据被置乱

Java TCP套接字数据被置乱,java,sockets,tcp,Java,Sockets,Tcp,我有一个多线程TCP套接字侦听程序。我对特定字节数(128字节和4倍)的数据执行阻塞读取,因此我的数据包大小为128字节、256字节、384字节和512字节 我遇到了问题,因为有时候数据在套接字中被弄乱了。例如: 应该是: <header><data payload(padded with zeros to compensate size)><footer> getdata()方法如下所示: String msg = "";//the return Stri

我有一个多线程TCP套接字侦听程序。我对特定字节数(128字节和4倍)的数据执行阻塞读取,因此我的数据包大小为128字节、256字节、384字节和512字节

我遇到了问题,因为有时候数据在套接字中被弄乱了。例如:

应该是:

<header><data payload(padded with zeros to compensate size)><footer>
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;
String msg=”“//返回字符串
整数计数=1;
对于(int i=0;i=startindex){
如果(当你这样做时计数)

int lengthActuallyRead = in.read(rec_data_in_byte1, 0, 128);
您需要检查读取的长度。否则,它可能会读取1个字节,或者在本例中最多读取128个字节。请注意,实际读取内容之后的任何字节都不会被触及,因此它们可能是
0
,也可能是前一条消息留下的垃圾

如果需要128个字节,则可以像以前一样轻松地使用

in.readFully(rec_data_in_byte, 0, 128);
注意:如果剩余金额小于128,您可能需要执行此操作

int remaining = size - sizeReadSoFar;
int length = in.read(rec_data_in_byte1, 0, remaining);

这将阻止您在仍在阅读旧消息时阅读下一条消息的一部分。

我的协议在客户端设计为仅发送128字节的数据包,最多4倍,因此读取的数据将始终是128字节,并且是它的倍数。此外,现在编辑代码时,读取的数据已完全就绪,因此可以达到目的。但我的question残留物数据会被扰乱/弄乱吗?@JayeshTripathi数据在线路上没有损坏,但如果您没有正确读取数据,它可能会损坏。因此,根据我对代码的编辑和您的建议,现在应该可以解决问题了。对吗?@JayeshTripathi是的。您可能希望使用BufferedInputStream来减少实际的re数量操作系统上的广告。我回滚了你上次的编辑。你的编辑使Peter Lawrey给出的答案无效。如果你听从Peter的建议,那么要么问一个新问题,要么更新你的问题以添加你尝试过的新东西和你看到的东西。请注意,你还应该包括用于编写数据的代码。这个问题也可以是be在那里。@Mark Rotteveel谢谢你的建议。从现在开始,他将这样做。stackoverflow世界的新成员。在所有更新和回滚之后,你仍然有一个
read()
方法,其返回值你没有使用。你需要在任何地方使用
readFully()
或不假设
read()的适当代码
填充了缓冲区。TCP是一个字节流,不必一次交付多个字节。为什么这个问题被标记为“多线程”?您说代码示例来自一个多线程程序,但您的问题没有询问任何关于线程的问题,您的示例代码也没有创建任何线程或执行任何线程同步或线程之间的通信。好的,所以“Java”是合适的,因为您正在寻找了解Java及其库的人;“sockets”是合适的(假设变量
conn
java.net.Socket
)“Tcp”是可以的:您的问题并不是专门关于Tcp协议,而是与Tcp套接字的行为有关。这里真正不属于的唯一标记是“多线程”“由于您对线程一无所知,因此请不要给出与线程相关的代码示例,也不要暗示多线程可能与您的问题有关。
in.readFully(rec_data_in_byte, 0, 128);
int remaining = size - sizeReadSoFar;
int length = in.read(rec_data_in_byte1, 0, remaining);