读取()时BufferedReader阻塞 [英] BufferedReader blocking at read()

查看:666
本文介绍了读取()时BufferedReader阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用服务器和客户端创建一个简单的聊天程序,现在我的问题是程序在从服务器读取消息到客户端时阻塞,反之亦然。此示例解决了从客户端到服务器的消息问题。

Im trying to create a simple chat program, with a "server" and a client, now my problem is that the program blocks while reading messages from the server to the client and vice-versa. This example features the problem with messages from Client to Server.

我在服务器端的示例:

private Reader input;
private Writer output;

try {

        server = new ServerSocket(this.port);

        while (true) {

            Socket connection = server.accept();

            serverDisplay("We have a connection");

            input = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            output = new BufferedWriter(new OutputStreamWriter(
                    connection.getOutputStream()));

            int c;
            StringBuffer sb = new StringBuffer();

            // This is where it blocks, the input stream should return -1 at the end of the
            // stream and break the loop, but it doesnt
            while ((c = input.read()) != -1) {
                sb.append((char) c);
            }
            serverDisplay(sb.toString());
        }

    } catch (IOException e) {
        System.out.println("IO ex in the server");
    }

为了在客户端发送消息,我有以下代码:

For sending message on the client side I have the following code:

output = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));

private void sendMessage(String message) {
    displayMessage(message);

    try {
        output.write(message);
        output.flush();
    } catch (IOException e) {
        System.out.println("IO ex at sendMessage client");
    }

}

它读取我发送的所有字符(从客户端到服务器;通过Sys确认)但当它应该读取流的末尾(-1)时它会挂起

It reads all the characters I send (from client to server; confirmed with Sys out) but when it is supposed to read the end of the stream (-1) it hangs there.

我试图在while循环中打印c以查看它返回的值,它根本不会进入循环,也不会破坏它,它只是挂在那里。

I have tried to print the "c" inside the while loop to see the value it returns and it simply doesn't go in the loop neither does it break it, it just hangs there.

我知道有一些问题已经与这个问题有关但我没有找到解决我问题的方法。

I'm aware there are a few questions already related to this subject but I haven't found the solution to my problem in any of them.

奇怪(至少对我来说)如果我使用

Oddly enough (at least for me) if I use:

output = new ObjectOutputStream(connection.getOutputStream());
input = new ObjectInputStream(connection.getInputStream());

和:

while ((message = (String) input.readObject()) != null)

而不是:

input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
output = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));

并且:

while ((c = input.read()) != -1) 

洞的事情有效。然而,这不是我想要的方式,通过读取BufferedReader / Writer的API,输入/输出StreamStritWriter,我认为我的代码应该可行。

The hole thing works. However this is not how I want to do it, and by reading the API's of the BufferedReader/Writer, Input/OutputStreamWriter I would think my code should work.

谢谢事先。

推荐答案

直到发送流(或整个套接字)为止,才会到达接收方端的流末端关闭。

The end of stream on the receiver side isn't reached until the sending stream (or entire socket) is closed.

发送方的output.close()将导致接收方看到流的结束。

output.close() on the send side will cause the receive side to see end of stream.

如果需要将流用于多个消息,则需要在应用程序协议中引入帧结构,以便接收方可以确定消息边界。这可以简单到为每条消息添加消息长度(以字节为单位)。

If you need to use the stream for multiple messages, you'll need to introduce a frame structure in to your application protocol so that receiver can determine message boundaries. This can be as simple as prefixing the length of the message in bytes to each message.

因为您使用String作为整个消息。您可以使用 DataInputStream DataOutputStream 流装饰器使用 readUTF() writeUTF(String)为您构建消息 writeUTF(String)基本上通过在写入字符串之前将其长度写入流来构造字符串。 readUTF()然后读取此长度,然后知道在返回之前需要从流中读取多少数据。

Since you are using a String as your entire message. You can use DataInputStream and DataOutputStream stream decorators to frame the message for you with readUTF() and writeUTF(String). writeUTF(String) basically frames the string by writing its length to stream before writing the string. readUTF() then reads this length and then knows how much data it needs to read off the stream before returning.

输出:

DataOutputStream output = new DataOutputStream(connection.getOutputStream());

private void sendMessage(String message) {
    displayMessage(message);

    try {
        output.writeUTF(message);
        output.flush();
    } catch (IOException e) {
        System.out.println("IO ex at sendMessage client");
    }

}

输入:

DataInputStream input = new DataInputStream(connection.getInputStream());

String message = input.readUTF();

serverDispaly(message);

这篇关于读取()时BufferedReader阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆