簡體   English   中英

BufferedReader在read()處阻塞

[英]BufferedReader blocking at read()

我試圖創建一個帶有“服務器”和客戶端的簡單聊天程序,現在我的問題是該程序在從服務器讀取消息到客戶端時會阻塞,反之亦然。 此示例解決了從客戶端到服務器的消息問題。

我在服務器端的示例:

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");
    }

為了在客戶端發送消息,我有以下代碼:

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 out確認),但是當應該讀取流的末尾(-1)時,它將掛在那里

我試圖在while循環中打印“ c”以查看其返回的值,並且它根本不會進入循環,也不會中斷它,它只是掛在那里。

我知道已經有一些與此主題相關的問題,但是我沒有找到解決我問題的方法。

奇怪的是(至少對我來說), 如果我使用

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,Input / OutputStreamWriter的API,我認為我的代碼應該可以工作。

先感謝您。

在關閉發送流(或整個套接字)之前,不會到達接收器端的流的末尾。

發送方的output.close()將使接收方看到流的結尾。

如果需要將流用於多條消息,則需要在應用程序協議中引入幀結構,以便接收方可以確定消息邊界。 這可以很簡單,只需在每條消息的前綴以字節為單位的消息長度。

由於您使用字符串作為整個消息。 您可以使用DataInputStreamDataOutputStream流裝飾器通過readUTF()writeUTF(String)為您構造消息。 writeUTF(String)基本上是通過在寫入字符串之前將其長度寫入流來構架該字符串。 readUTF()然后讀取此長度,然后知道在返回之前需要從流中讀取多少數據。

例:

輸出:

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM