我们在做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的阻塞问题。