Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 349|回复: 0

Java socket中使用bufferreader处理头部请求信息时,用readline()方法会阻塞问题的可行解决方案

[复制链接]
  • TA的每日心情
    奋斗
    昨天 13:08
  • 签到天数: 776 天

    [LV.10]以坛为家III

    2046

    主题

    2104

    帖子

    71万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    714508
    发表于 2021-6-23 11:19:22 | 显示全部楼层 |阅读模式

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

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-8-16 08:50 , Processed in 0.058804 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表