套接字readline没有阻塞

时间:2013-09-04 16:38:02

标签: java sockets

正在将事件转发到客户端套接字,该代码正由以下代码读取。大多数情况下代码按预期工作。有时,数据包被发送到套接字,这导致readline以空消息解除阻塞。从那时起,readline调用永远不会再次阻塞,导致CPU峰值。我已用代码验证套接字未关闭,输入流尚未关闭,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);
    }
}

3 个答案:

答案 0 :(得分:3)

当另一端关闭连接时,

BufferedReader.readLine()返回null

如果没有这样做,你就会遇到一个特别错误的JVM。我会确保你有最新的更新。

  

我已用代码验证套接字未关闭,输入流未关闭,isSocketClosed和isInputShutdown都返回false

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

  

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

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

答案 1 :(得分:0)

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

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

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

  

返回此字符串的长度。长度等于数字   字符串中的Unicode code units。 @return的长度   此对象表示的字符序列。

答案 2 :(得分:0)

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

测试ready()和sleeps的循环部分实际上是浪费时间。删除它。