簡體   English   中英

套接字輸入流在最終讀取時掛起。 最好的處理方法?

[英]Socket input stream hangs on final read. Best way to handle this?

我對如何避免我的套接字掛起讀取有點難過。 這是我的代碼:

    Socket socket = new Socket("someMachine", 16003);
    OutputStream outputStream = socket.getOutputStream();
    InputStream inputStream = socket.getInputStream();
    try {
        outputStream.write(messageBuffer.toByteArray());
        outputStream.flush();
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
        StringBuffer response = new StringBuffer();
        int result;
        while ((result = in.read()) != -1) {
            response.append(Character.toChars(result));
            System.out.println(result);
        }
        System.out.println("Done!");  //never gets printed
     } catch (...) {}

上面的代碼成功地從流中讀取了所有數據,但隨后掛起。 在網上閱讀我希望從服務器(我無法控制)收到 -1 以表明我已經到達流的末尾,但我得到了這個:

(Lots of data above this point)
57
10
37
37
69
79
70
10

然后掛起。 所以,我的問題是:

1)我是否編碼錯誤或服務器的響應有問題?

2)如果服務器的響應有問題(即沒有返回-1),我該如何解決這個問題(即當它掛起時停止讀取)。

任何幫助表示贊賞!

僅僅在 read 掛起的地方停止的問題是這可能發生在 2 種情況下:

1:服務器沒有更多數據要發送

2:服務器發送了更多的數據,但是由於網絡過載,您的客戶端還沒有收到。

而且您只想在第一種情況下真正停止閱讀,但您希望在第二種情況下閱讀阻止。

解決這個問題的方法是制定一個傳輸協議(標准),它允許服務器告訴客戶端它期望發送多少數據。

如果服務器事先知道總數據大小,只需從發送傳輸中的總字節數開始,然后發送數據。 這樣客戶端就知道它何時收到了所有數據。

(或者服務器可以在完成后簡單地關閉連接。這樣read應該會失敗,但這僅在您將來不需要連接時才有效)

我想你只會在服務器決定停止對話時得到-1,即關閉它的輸出流或完全關閉套接字。 否則,該流對未來可能的傳入數據保持打開狀態。

我不是 Android 專家,但這似乎在 Android 上運行良好:

    try {
        telnetClient = new Socket(server, port);
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    if (telnetClient.isConnected()) {
        try {
            InputStream instr = telnetClient.getInputStream();
            int buffSize = telnetClient.getReceiveBufferSize();
            if (buffSize > 0) {
                byte[] buff = new byte[buffSize];
                int ret_read = instr.read(buff);
                screen.append(new String(buff, 0, ret_read));
            }
        } catch (IOException e) {
            screen.append("Exception while reading socket:" + e.getMessage());
        }
    }

我剛剛遇到了同樣的問題。 我通過在創建套接字對象后直接設置超時來解決它... socket.setSoTimeout(10 * 1000);

我發現這個問題非常棘手。 我試圖從java執行一個windows批處理命令,每次嘗試從執行的命令中讀取輸入流時,進程都會掛起。

我只能粗魯地解決這個問題。

a)通過查找我知道的特定行,它將從流中發出最終有用信息的信號。
b)或者啟動一個新的線程來殺死套接字另一端的進程,在這種情況下,對我來說是 IEDriverServer.exe 在等待時間之后。

String[] cmdArray = {"cmd.exe","/c",cmd+ " 2>&1" };
    InputStream is = new ProcessBuilder(cmdArray).directory(f).start().getInputStream();

        error_buffer = new BufferedReader(new InputStreamReader(is));
        int lines=0;

        while((line=error_buffer.readLine())!=null){
            if(line.startsWith("[INFO] Final Memory: ")) {
                break;
            }

            log.debug("Reading cmd Stream "+line);
            buf.append(line);
            lines++;
        }

嘗試:

while ((result = in.read()) != null) {

暫無
暫無

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

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