简体   繁体   English

套接字读线未阻塞

[英]Socket readline not blocking

Events are being forwarded to a client socket, which is being read by the code below. 事件被转发到客户端套接字,下面的代码正在读取该套接字。 Most of the time the code works as expected. 大多数情况下,代码按预期运行。 Sometimes a data packet is sent to the socket which causes the readline to unblock with a null message. 有时,数据包会发送到套接字,这会导致读取行以空消息取消阻塞。 From that point forward, the readline call never blocks again, causing a CPU spike. 从那时起,readline调用再也不会阻塞,从而导致CPU峰值。 I have verified with code that the socket is not closed, the input stream has not been shutdown, isSocketClosed and isInputShutdown both return false. 我已使用代码验证了套接字未关闭,输入流尚未关闭,isSocketClosed和isInputShutdown均返回false。 The ready call is just an attempt to see what's happening, the read call always returns -1. 准备调用只是尝试查看正在发生的事情,读调用始终返回-1。 The socket is still accepting data, new valid packets come in, processed correctly, but the readline never blocks again. 套接字仍在接受数据,新的有效数据包进入,正确处理,但读取行再也不会阻塞。 Any idea how why readline is behaving this way? 知道为什么readline如何表现这种方式吗?

while (!this.isInterrupted())
{
    String message = null;
    do {
        message = reader.readLine();
        if ( message != null && message.length() > 0 ) {
            //if ( log().isDebugEnabled())
                log().info( "Got a message, raw data: " + message );
            createEvent( message );
        }
    } while ( message != null && !this.isInterrupted());

    if(!reader.ready()) {
        log().info("Bytes read: " + reader.read());
        Thread.sleep(1000);
    }
}

BufferedReader.readLine() returns null when the other end closes the connection. 当另一端关闭连接时,BufferedReader.readLine()返回null

If it is not doing this you have a particularly bug JVM. 如果未执行此操作,则说明您的JVM特别错误。 I would make sure you have the latest update. 我将确保您具有最新更新。

I have verified with code that the socket is not closed, the input stream has not been shutdown, isSocketClosed and isInputShutdown both return false 我已经使用代码验证了套接字未关闭,输入流尚未关闭,isSocketClosed和isInputShutdown均返回false

This just means your end didn't close() the stream. 这只是意味着您没有close()流。 It doesn't tell you anything about the other end of the stream. 它没有告诉您有关流另一端的任何信息。

The ready call is just an attempt to see what's happening, the read call always returns -1 准备调用只是尝试查看发生了什么,读调用始终返回-1

This also means you have an end of stream. 这也意味着您已经结束了流。

Just a small thing, but if you have empty (not null) strings coming in on your socket, they won't fall under if ( message != null && message.length() > 0 ) . 只是一件小事,但是如果套接字中有空字符串(不是null),它们将不属于if ( message != null && message.length() > 0 )

You might wanna change it to if ( message != null ) . 您可能想将其更改为if ( message != null )

The reason this happens comes from the String#length() method: 发生这种情况的原因来自String#length()方法:

Returns the length of this string. 返回此字符串的长度。 The length is equal to the number of Unicode code units in the string. 长度等于字符串中Unicode代码单元的数量。 @return the length of the sequence of characters represented by this object. @返回此对象表示的字符序列的长度。

You have a bug in your code. 您的代码中有一个错误。 If readLine() returns null, it means the peer has closed the connection. 如果readLine()返回null,则意味着对等方已关闭连接。 You must do likewise and exit the loop. 您必须同样执行并退出循环。 Once it has returned null, it will never block again, and it will never stop returning null. 一旦返回null,它将永远不会再次阻塞,也永远不会停止返回null。

The part of your loop that tests ready() and sleeps is literally a compete waste of time. 循环中测试ready()和sleep的部分实际上是在浪费时间。 Remove it. 去掉它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM