1

事件被转发到客户端套接字,下面的代码正在读取该套接字。大多数情况下,代码按预期工作。有时数据包被发送到套接字,这会导致 readline 以空消息解除阻塞。从那时起,readline 调用不再阻塞,从而导致 CPU 峰值。我用代码验证了socket没有关闭,输入流没有关闭,isSocketClosed和isInputShutdown都返回false。就绪调用只是尝试查看正在发生的事情,读取调用总是返回-1。套接字仍在接受数据,新的有效数据包进来,被正确处理,但 readline 不再阻塞。知道为什么 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);
    }
}
4

3 回答 3

3

BufferedReader.readLine()null在另一端关闭连接时返回。

如果它不这样做,那么你有一个特别错误的 JVM。我会确保你有最新的更新。

我用代码验证了socket没有关闭,输入流没有关闭,isSocketClosed和isInputShutdown都返回false

这只是意味着你的结局没有close()流。它不会告诉您有关流的另一端的任何信息。

就绪调用只是尝试查看正在发生的事情,读取调用总是返回 -1

这也意味着你有一个流的结束。

于 2013-09-04T16:48:06.887 回答
0

只是一件小事,但是如果您的套接字上有空(非空)字符串,它们将不会落入if ( message != null && message.length() > 0 ).

您可能想将其更改为if ( message != null ).

发生这种情况的原因来自String#length()方法:

返回此字符串的长度。长度等于 字符串中Unicode 代码单元的数量。@return 此对象表示的字符序列的长度。

于 2013-09-04T17:49:15.490 回答
0

您的代码中有错误。如果 readLine() 返回 null,则表示对端已关闭连接。您必须这样做并退出循环。一旦它返回了null,它就再也不会阻塞,也永远不会停止返回null。

测试 ready() 和 sleep 的循环部分实际上是在浪费时间。去掉它。

于 2013-09-04T18:20:34.910 回答