我們在做Java socket編程時,有時候為了方便會選擇使用buffereader進行頭部信息的處理。但有時候也會遇到一些問題。比如標題所說的阻塞問題。
for example:
1 BufferedReader br; 2 3 while (line != null) { 4 line = br.readLine(); 5 }
這樣循環讀的話,當到達最后一行時,br會繼續讀下一行,直到找到“\r\n”才會返回null,反之,則會一直尋找,導致阻塞。
在處理post請求時,我們總會不可避免的遇到多行數據,如果使用readline的方法去讀,則會阻塞。那么我們有沒有什么別的解決方法呢?
答案是肯定的!
1 StringBuffer param = new StringBuffer(); 2 String lineParam; 3 while (contentLength > 0) { 4 lineParam = br.readLine(); 5 contentLength -= lineParam.getBytes().length; 6 param.append(lineParam); 7 param.append("\r\n"); 8 } 9 System.out.println(param);
在post請求的頭部中,有個contentLength屬性,我們可以在解析的時候獲得這個屬性的值。
while (line != null) { line = br.readLine(); if (line.equals("")) { break; } else if (line.indexOf("Content-Length") != -1) { contentLength = Integer.parseInt(line.substring(line.indexOf("Content- Length") + 16)); } }
當獲取這個值之后,我們的報文體里面的內容長度就可知。那么我們就可以根據contentLength屬性作為readline循環讀時循環判斷屬性。
但發現還是會進行阻塞。通過一番debug后發現,原來contentLength包含了消息體里面的“\r\n”即換行字符的長度,而我們那樣判斷的時候卻忽略了這個長度,所以,稍加改進后,我們有了下面的一種可行方案:
StringBuffer param = new StringBuffer(); String lineParam; //判斷讀取了幾行數據 int size = 0; while (contentLength > size) { lineParam = br.readLine(); size++; contentLength -= lineParam.getBytes().length; param.append(lineParam); param.append("\r\n"); } System.out.println(param);
如此,我們便解決了readline的阻塞問題。