连续读取套接字的所有输入

时间:2011-12-09 07:45:18

标签: java sockets stream

我正在编写一个简单的Java客户端/服务器应用程序供我自己使用。它应该允许客户端发送单行文本消息并读取多行响应。使用相同的连接,这种通信应该可重复多次。

这是我在客户端阅读回复的内容:

BufferedReader input = new BufferedReader(new InputStreamReader(server.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
    // processing here
}

问题在于,一旦服务器发回第一个响应,readLine()就会阻塞,因此客户端无法发送新消息。这是可以理解的。一个简单的解决方法可能是通过发送某种已知的特殊字符串值使服务器信号输出结束,然后客户端将识别并终止读取循环。但是,这个问题有更好的解决方案吗?

2 个答案:

答案 0 :(得分:4)

由于您的客户应该从同一连接读取多个多行响应并处理每个响应块, 这可能对您的情况有用:

    BufferedReader input = new BufferedReader(new InputStreamReader(server.getInputStream()));
    String line;
    StringBuilder sb = new StringBuilder();
    while ((line = input.readLine()) != null) {
        if (line.equals("~~/START/~~"))
            sb = new StringBuilder();
        else if (line.equals("~~/END/~~")) {
            doSthWithParagraph(sb.toString());
            sb.delete(0, sb.length());
        } else
            sb.append(line);
    }

您可以使用自己的特殊字符串来识别每个消息块的开始和结束。

答案 1 :(得分:1)

我不会依赖readLine作为主循环,因为readLine依赖于“未来”数据(CR,或LF或CR + LF,如果已达到流末尾则返回null )。因此,如果CR后面没有LF,则BufferedReader会被卡住。此readLine方法更适合读取文件内容。

在你的情况下,我会一次用

读一个字
while ((myChar = input.read()) != -1) {
    // processing here, storing information in a buffer and taking appropriate actions if
    // A CR or LF is found
}

但即使这种行为也是可疑的,因为Unicode char可能超过一个字节,因此如果发送第一个字节而不是第二个字节,则流可能会卡住。您确定您的通信是Unicode吗?如果不是,则InputStreamReader更合适。