java - TCP 套接字数据变得困惑

标签 java sockets tcp

我有一个多线程 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/

相关文章:

java - 如何在 Java 中表示 TCP 端口范围(16 位)

networking - 浏览器如何通过80端口与Web服务器建立连接?细节?

java - Android 中未找到 WheelView

java - 无法从 [Source : java. io.StringReader@505fd738; 处的 START_OBJECT token 反序列化 java.util.ArrayList 实例;行 : 1, 列:1]

java - 在没有类型安全警告的情况下覆盖通用抽象方法的返回类型

c# - 为服务器应用程序使用 3 个端口是否明智?

java - 当 url 包含大括号字符时 Spring-boot Controller 出错

macos - getaddrinfo 可以返回哪些地址族?

c++ - 如何向客户端重播 TCP 流

linux - 如何在Linux中设置最大TCP接收窗口大小?