伺服器和客戶端之間互動時使用BufferedReader的阻塞問題
阿新 • • 發佈:2019-02-02
1.遇到的問題
Socket socket = serverSocket.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("接受完了!");
上面的程式碼用於在伺服器上面接受客戶端的資料。可是while迴圈永遠無法停止,下面的“接受完了”也打印不出來!
2.問題分析:
(1)BufferedReader的readLine方法只有在遇到流結尾或者流關閉了才會返回null
(2)對於讀取檔案流,當讀到檔案的結尾時,就是到了流的結尾
(3)但對於socket,不能認為把某次寫入到流中的資料讀取完了就算流結尾了,但是socket流還存在,還可以繼續往裡面寫入資料然後再讀取。所以用BufferedReader封裝socket的輸入流,呼叫BufferedReader的readLine方法是不會返回null的
3.還有一種情況,即用InputStream去讀,和上面也是一樣的錯誤:
byte[] buf = new byte[1024]; InputStream in = socket.getInputStream(); int i=0; while((i=in.read(buf))!=-1){ String s = new String(buf); System.out.println(s); } System.out.println("接受完了!");
4.這是我在看tomcat原始碼的時候,自己寫的一個ServerDemo時犯的錯誤。用於我們想獲得的只是客戶端發來的HTTP請求,HTTP請求不會太大,所以可以定義一個不是很大的緩衝區把資料存到緩衝區中去。
byte[] buf = new byte[2048]; InputStream in = socket.getInputStream(); int i = in.read(buf); String request = new String(buf,0,i); System.out.println(request); System.out.println("接受完了!");
5.還有一種方式,經過測試,也可以行得通:
Socket socket = serverSocket.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null && line.length()!=0) {
System.out.println(line+"-------------");
}
System.out.println("接受完了!");