簡體   English   中英

如何使用套接字流在BufferedReader上設置超時

[英]How to set a timeout on a BufferedReader with a socket stream

這里我創建一個線程來檢查每2秒的服務器響應,問題是client.monitorResponse()是一個readLine()方法,並且在收到響應之前不會繼續。

client = new ClientObject("localhost");
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        try {
            String response = null;
            if(!(response = client.monitorResponse()).isEmpty()) {
                System.out.println("Response: " + response);
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
}, 2000, 2000);

我通過服務器發送響應,如此( client是已建立的Socket):

public SocketObject(Socket client, int numberOfClients) throws Exception {
    socket = client; // the .accept() socket is passed through
    // this is because I assign them ID's for later use (I hold an ArrayList of sockets)
    this.clientId = numberOfClients;

    // both these are static to the class

    outputStream = new PrintWriter(client.getOutputStream());
    inputStream = new BufferedReader(new InputStreamReader(client.getInputStream()));
}

public void sendResponse(String response) {
    outputStream.println(response);
}

然后,我通過已連接到服務器的客戶端Socket選擇響應:

public ClientObject(String hostname) throws IOException {

    // socket is static to this class

    socket = new Socket(hostname, 4444);
    System.out.println("Connected to " + hostname + " on port 4444...");

    // both static to this class

    outputStream = new PrintWriter(socket.getOutputStream(), true);
    inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    System.out.println("Successfully started a stream on " + hostname);
    this.hostname = hostname;
}

public String monitorResponse() throws Exception {
    System.out.println("Listening for a response...");
    return inputStream.readLine();
}

調試控制台只顯示一個偵聽響應...輸出,它告訴我它沒有通過Thread內部的inputStream.readLine()方法。 無論如何我可以在BufferedReader上添加超時嗎? 我已經嘗試了多種解決方案,比如在創建BufferedReader之前向套接字添加.setSoTimeout() ,但所有這些都是在指定時間后關閉連接/套接字。

任何幫助,將不勝感激。

您應該使用非阻塞(NIO)請求並讀取塊以查找中間的換行符。 通常在Java中,您只需要查找正在使用的Stream類的NIO版本,並使用它來檢查新內容的每N秒。 在您進行最少修改的情況下,您可以使用BufferedReader.ready()阻止調用的不那么花哨和有效的方法來防止阻塞:

String partialLine="";
public static String monitorResponse() throws Exception {
    System.out.println("Listening for a response...");
    int nextByte;
    String nextChar;
    while (inputStream.ready()) {
        nextByte = inputStream.read();
        nextChar = Character.toString ((char) nextByte);
        partialLine += nextChar;
        if ("\n".equals(nextChar)) {
            String line = partialLine;
            partialLine = "";
            return line.replace("\r\n", "");
        }
    }
    return "";
}

查看http://tutorials.jenkov.com/java-nio/nio-vs-io.html了解更多信息。

無論如何我可以在BufferedReader上添加超時嗎?

不,但您可以使用Socket.setSoTimeout()Socket上設置超時。

我已經嘗試了多種解決方案,比如在創建BufferedReader之前向套接字添加.setSoTimeout(),但所有這些都是在指定時間后關閉連接/套接字。

不,它沒有關閉插座。 它拋出SocketTimeoutException ,你應該捕獲並處理相關的。 如果套接字正在關閉,您將關閉它。 解決方案:不要。

暫無
暫無

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

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