1. 程式人生 > >伺服器和客戶端之間互動時使用BufferedReader的阻塞問題

伺服器和客戶端之間互動時使用BufferedReader的阻塞問題

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("接受完了!");