【问题标题】:Delay in reading TCP socket data读取 TCP 套接字数据的延迟
【发布时间】:2017-08-04 06:27:19
【问题描述】:

我正在尝试使用inputStream.available() 连续读取 tcp 套接字上的数据字节计数。如果返回值大于 0,则使用inputStream.read(byte[inputstream.available()] b) 从 TCP 读取数据。但只有当我们收到带有 [PSH,ACK] 的数据(在 Wireshark 中)时,它才会返回计数。当只有具有 [ACK] 的数据(在 wireshark 中)时,它每次都返回 0,直到没有收到具有 [PSH,ACK] 的数据。只有当服务器需要发送大量数据时才会发生(不知道服务器实现)。

这里是sn-p的代码:

while(inputStream.available()>0){
    byte [] bytesFromServer=new byte[inputStream.available()]
    inputStream.read(bytesFromServer);
}

问题是:- 1.我可以不用担心数据中的[PSH,ACK]或[ACK]标志读取数据吗? 2. 为什么服务器端有[PSH,ACK]标志的数据需要时间。

【问题讨论】:

    标签: java sockets tcp


    【解决方案1】:

    我正在尝试使用inputStream.available(). 连续读取 tcp 套接字

    这是你的第一个错误。 InputStream.available() 不读取数据:它只提供了一个估计,可以在不阻塞的情况下读取多少数据。如果您尝试连续阅读,则根本不需要available()。只需调用read() 方法之一,最好是采用(大)字节数组的方法。

    只有当我们收到带有 [PSH,ACK] 的数据(在 Wireshark 中)时,它才会返回计数。当只有具有 [ACK] 的数据(在 wireshark 中)时,它每次都返回 0,直到没有收到具有 [PSH,ACK] 的数据。只有当服务器需要发送大量数据时才会发生(不知道服务器实现)。

    available() 返回什么并不重要。令人惊讶的是,您的平台实际上实现了 PSH 标志,但无论如何您都应该阻止 read()。其他任何策略都没有意义。

    问题是: 1. 可以不用担心数据中的[PSH,ACK]或[ACK]标志读取数据吗?

    是的。

    1. 为什么来自服务器的带有 [PSH,ACK] 标志的数据需要时间。

    不知道,但这无关紧要。

    while(inputStream.available()>0){
        byte [] bytesFromServer=new byte[inputStream.available()]
        inputStream.read(bytesFromServer);
    }
    

    除了每次读取两次系统调用外,此代码还会引发垃圾收集狂潮,并且不会读取到流的末尾。试试这个:

    byte [] bytesFromServer=new byte[8192]; // or double or quadruple if you like
    int count;
    while ((count = inputStream.read(buffer)) > 0) {
        // do something with buffer[0..count-1]
    }
    

    【讨论】:

    • 我认为, inputStream.available() 将读取 TCP 套接字并重新运行可读取的套接字上可用的字节数。在这里,我尝试使用此方法连续读取可用字节数是数据/或字节数大于 0,而不是仅尝试使用 read() 或 read(byte[inputstream.available()] 读取数据)。
    • 我是 TCP 网络的新手。我的观察是,只有当具有 [PSH,ACK] 的数据到达套接字时,java .available 方法才会返回计数,否则只会返回 0。因此,如果 available() 计数为零,我将不会读取数据,因为我不知道需要读取的字节大小。
    • InputStream.available() 将返回一个 估计 可在不阻塞的情况下读取的字节数。请参阅 Javadoc。这是一个额外的系统调用。知道是没有用的。你仍然需要读取,这是另一个系统调用,read() 返回一个计数,这是你设法从available() 中得到的所有值,那么为什么要加倍系统调用呢?您不需要知道要读取的字节数:只需使用足够大的缓冲区即可。
    • 我试过 read(byte[] bytes) 仍然有延迟。我以为我会在收到标志 [PSH,ACK] 之前读取数据 我的观察是:- Java 只能在获得标志 [PSH,ACK] 后从 TCP 读取数据,函数将等到它获得具有此标志的数据包.
    • @Amityadav 这不是 Java,而是平台。除了确保发件人设置 PSH 标志外,任何人都无能为力。什么是客户端平台?
    猜你喜欢
    • 2013-03-13
    • 2020-02-07
    • 2014-03-23
    • 1970-01-01
    • 2013-06-21
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 2015-12-15
    相关资源
    最近更新 更多