写了一个简单的web后台,用socket接收并解析http请求。然而在网页发出第一次请求时总会卡住(其实是流阻塞了),刷新后可以访问。以及总是读取不到最后一部分数据。

刚开始是这样写的

private String getStringFromIOStream(InputStream ios){BufferedReader reader = new BufferedReader( new InputStreamReader(ios));StringBuilder ret = new StringBuilder();String tstr=null;while ((tstr=reader.readLine()) != null) {ret.append(tstr).append("\n");System.out.println(tstr);}return ret.toString();
}

查看线程信息发现是阻塞在了“tstr=reader.readLine()”这一行。得知是socket输入流读取信息阻塞了,可以理解阻塞在了信息最后一行。于是给socket对象添加超时,并处理异常,如下:

Socket client = tm.serverSocket.accept();
client.setSoTimeout(10); // 这里设置超时时长为10毫秒,对于读取http请求足够了
private String getStringFromIOStream(InputStream ios){BufferedReader reader = new BufferedReader( new InputStreamReader(ios));StringBuilder ret = new StringBuilder();String tstr=null;try {while ((tstr=reader.readLine()) != null) {ret.append(tstr).append("\n");System.out.println(tstr);}}catch (IOException e){ // 读取完成时,超时会报异常,结束阻塞。}return ret.toString();
}

这是一旦超时便出发异常,从而解决了阻塞的问题。正在感觉完事大吉时,发现接收不到post请求发来的参数,而http请求,post的参数正是数据的最后一行。于是想到应该是http请求最后没有换行,所以readLine()阻塞在了最后一行数据上,而一旦发生异常,最后一行数据就拿不到了。想过添加参数,但发现添加了参数的Http请求,将所有参数封装在了同一行上,解决。于是换思路,考虑使用字节流解析来避免丢失最后一行数据的问题。代码如下

    private String getStringFromIOStream(InputStream ios) {int byteArrLen = 128;byte[] bytes = new byte[byteArrLen];StringBuilder ret = new StringBuilder();int len = byteArrLen;try{while ((len=ios.read(bytes)) != -1 ){ // 当客户端主动中断连接时此处会返回-1ret.append(new String(bytes,0,len)); // 在最后一次读取,len会小于数组大小,此处设置len避免末尾无效数据System.out.println(new String(bytes,0,len));if(len<byteArrLen){   // 获取不到预定大小说明可以结束break;}}}catch (IOException e){ // 超时结束}return ret.toString();}

有4处细节需要注意,都写在上面备注里了。其中三处是结束循环,都不可少。

Socket通过读取数据阻塞的解决方案相关推荐

  1. Java Socket正确读取数据姿势

    前言 平时日常开发用得最多是Http通讯,接口调试也比较简单的,也有比较强大的框架支持(OkHttp). 个人平时用到socket通讯的地方是Android与外设通讯,Android与ssl服务通讯, ...

  2. Java包数据消息头消息尾_读Socket流时产生阻塞的解决方案(粘包拆包问题)

    转自:https://www.cnblogs.com/qhyuan1992/p/5385289.html 其实最终讨论的是TCP通信过程中的粘包拆包(半包)问题. 在用socket写一个服务器时遇到了 ...

  3. 项目优化:当使用redis减少数据库压力时,遇到redis写入失败,造成读取数据问题的解决方案

    场景: 我们项目用到了mq,有一个专门的服务在跑异步任务去发mq,这个mq的数据不是从数据库里面查的,而是从redis里面取的,之所以这么做,有两个原因: 1.使用redis减少数据库的压力: 2.本 ...

  4. netty获取玩家chanel_netty源码解析(4.0)-14 Channel NIO实现:读取数据

    本章分析Nio Channel的数据读取功能的实现. Channel读取数据需要Channel和ChannelHandler配合使用,netty设计数据读取功能包括三个要素:Channel, Even ...

  5. live555从RTSP服务器读取数据到使用接收到的数据流程分析

    本文在linux环境下编译live555工程,并用cgdb调试工具对live555工程中的testProgs目录下的openRTSP的执行过程进行了跟踪分析,直到将从socket端读取视频数据并保存为 ...

  6. 实用 | 从Apache Kafka到Apache Spark安全读取数据

    引言 随着在CDH平台上物联网(IoT)使用案例的不断增加,针对这些工作负载的安全性显得至关重要.本篇博文对如何以安全的方式在Spark中使用来自Kafka的数据,以及针对物联网(IoT)使用案例的两 ...

  7. java套接字客户端_使用Java从客户端套接字读取数据(Read data from a client socket in Java)...

    使用Java从客户端套接字读取数据(Read data from a client socket in Java) 我编写了从客户端套接字发送/接收数据的代码. 发送数据步骤已成功完成,但是当我想从套 ...

  8. CBQ Web Part匿名读取Document Library数据失败的解决方案

    最近在项目当中遇到了一个很奇怪的问题,因为我们项目中用到了大量的 CBQ (Content By Query) Web Part 来在页面上呈现SharePoint List 或SharePoint ...

  9. Linux 使用fcntl c_cc[VMIN] c_cc[CTIME]设置串口阻塞与非阻塞读取数据

    一.概述 Linux串口非常灵活,可以根据需要配置成标准串口和自定义串口模式,就Linux 串口读取数据来说,有有两种主要方式:阻塞与非阻塞. 阻塞:一直等待数据,直到退出条件成立: 非阻塞:及时返回 ...

  10. python读取大数据量xml_[C#]_[使用微软OpenXmlSDK (OpenXmlReader)读取xlsx表格] 读取大数据量100万条数据Excel文件解决方案...

    1.OpenXmlSDK是个很好的类库,可惜只能通过C#调用,C#的童鞋又福气了. 2.服务端程序由于没法安装office,所以这个对asp.net网站来说是最理想的库了.需要.net 4.0版本以上 ...

最新文章

  1. 虚拟机VMware12下安装windows7 x64系统使用教程
  2. 电脑装机完没有efi_联想M910Q 黑苹果折腾系列③ Hackintosh opencore完善 EFI分享
  3. 由《我也能做CTO》引起的作者与读者的交流
  4. 第二章 物理层 1 物理层的基本概念 [计算机网络笔记]
  5. (28)css3 3D转换
  6. SPIR-V 研究:编译器基本原理
  7. PSD分层模板|电商促销海报设计技巧
  8. 「移动开发」iuap mobile玩转前端自动化构建
  9. list排序sort降序_list.sort和高阶函数sorted
  10. html iframe 设置半透明_HTML基础教程:框架实例大合集
  11. 计算器软件测试方法和技术,人工如何测试计算器
  12. PlatformIO开发STM8S003F3P6
  13. 1688接口:item_search - 按关键字搜索商品
  14. php 翻转180度,如何翻转视频—将视频翻转90或180度
  15. 台式计算机关机后自行重启,台式电脑关机后自动重启该怎么解决
  16. 湖北省211大学计算机分数线,武汉7所211大学湖北省录取分数线2020
  17. 自己捣鼓的小程序实现订单代付的功能
  18. 给女朋友写的简单的公众号推送信息程序
  19. 食堂总是拥挤不堪?解决用餐拥挤,教你一招
  20. android studio计时器怎么用,android - Android Studio:启动倒数计时器时应用崩溃

热门文章

  1. OpenVz Centos4 Oracle 10g VE
  2. oracle DBTIMEZONE时区调整
  3. C程序设计--指针(对 “ 多维数组 ” 进行输出操作)
  4. 数据库删除表中多列语法总结
  5. nyoj 1172 unlucky number
  6. 服务器位置设置,服务器部署位置
  7. 录屏软件电脑_电脑录屏用什么软件?电脑录屏软件集锦
  8. 二叉树的宽度 java_Java语言描述二叉树的深度和宽度
  9. 机器学习中的混淆矩阵,准确率,精确率,召回率,F1,ROC/AUC,AP/MAP
  10. python中的super用法详解_python中super的用法实例解析