[英]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.