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