Socket通过读取数据阻塞的解决方案
写了一个简单的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通过读取数据阻塞的解决方案相关推荐
- Java Socket正确读取数据姿势
前言 平时日常开发用得最多是Http通讯,接口调试也比较简单的,也有比较强大的框架支持(OkHttp). 个人平时用到socket通讯的地方是Android与外设通讯,Android与ssl服务通讯, ...
- Java包数据消息头消息尾_读Socket流时产生阻塞的解决方案(粘包拆包问题)
转自:https://www.cnblogs.com/qhyuan1992/p/5385289.html 其实最终讨论的是TCP通信过程中的粘包拆包(半包)问题. 在用socket写一个服务器时遇到了 ...
- 项目优化:当使用redis减少数据库压力时,遇到redis写入失败,造成读取数据问题的解决方案
场景: 我们项目用到了mq,有一个专门的服务在跑异步任务去发mq,这个mq的数据不是从数据库里面查的,而是从redis里面取的,之所以这么做,有两个原因: 1.使用redis减少数据库的压力: 2.本 ...
- netty获取玩家chanel_netty源码解析(4.0)-14 Channel NIO实现:读取数据
本章分析Nio Channel的数据读取功能的实现. Channel读取数据需要Channel和ChannelHandler配合使用,netty设计数据读取功能包括三个要素:Channel, Even ...
- live555从RTSP服务器读取数据到使用接收到的数据流程分析
本文在linux环境下编译live555工程,并用cgdb调试工具对live555工程中的testProgs目录下的openRTSP的执行过程进行了跟踪分析,直到将从socket端读取视频数据并保存为 ...
- 实用 | 从Apache Kafka到Apache Spark安全读取数据
引言 随着在CDH平台上物联网(IoT)使用案例的不断增加,针对这些工作负载的安全性显得至关重要.本篇博文对如何以安全的方式在Spark中使用来自Kafka的数据,以及针对物联网(IoT)使用案例的两 ...
- java套接字客户端_使用Java从客户端套接字读取数据(Read data from a client socket in Java)...
使用Java从客户端套接字读取数据(Read data from a client socket in Java) 我编写了从客户端套接字发送/接收数据的代码. 发送数据步骤已成功完成,但是当我想从套 ...
- CBQ Web Part匿名读取Document Library数据失败的解决方案
最近在项目当中遇到了一个很奇怪的问题,因为我们项目中用到了大量的 CBQ (Content By Query) Web Part 来在页面上呈现SharePoint List 或SharePoint ...
- Linux 使用fcntl c_cc[VMIN] c_cc[CTIME]设置串口阻塞与非阻塞读取数据
一.概述 Linux串口非常灵活,可以根据需要配置成标准串口和自定义串口模式,就Linux 串口读取数据来说,有有两种主要方式:阻塞与非阻塞. 阻塞:一直等待数据,直到退出条件成立: 非阻塞:及时返回 ...
- python读取大数据量xml_[C#]_[使用微软OpenXmlSDK (OpenXmlReader)读取xlsx表格] 读取大数据量100万条数据Excel文件解决方案...
1.OpenXmlSDK是个很好的类库,可惜只能通过C#调用,C#的童鞋又福气了. 2.服务端程序由于没法安装office,所以这个对asp.net网站来说是最理想的库了.需要.net 4.0版本以上 ...
最新文章
- 虚拟机VMware12下安装windows7 x64系统使用教程
- 电脑装机完没有efi_联想M910Q 黑苹果折腾系列③ Hackintosh opencore完善 EFI分享
- 由《我也能做CTO》引起的作者与读者的交流
- 第二章 物理层 1 物理层的基本概念 [计算机网络笔记]
- (28)css3 3D转换
- SPIR-V 研究:编译器基本原理
- PSD分层模板|电商促销海报设计技巧
- 「移动开发」iuap mobile玩转前端自动化构建
- list排序sort降序_list.sort和高阶函数sorted
- html iframe 设置半透明_HTML基础教程:框架实例大合集
- 计算器软件测试方法和技术,人工如何测试计算器
- PlatformIO开发STM8S003F3P6
- 1688接口:item_search - 按关键字搜索商品
- php 翻转180度,如何翻转视频—将视频翻转90或180度
- 台式计算机关机后自行重启,台式电脑关机后自动重启该怎么解决
- 湖北省211大学计算机分数线,武汉7所211大学湖北省录取分数线2020
- 自己捣鼓的小程序实现订单代付的功能
- 给女朋友写的简单的公众号推送信息程序
- 食堂总是拥挤不堪?解决用餐拥挤,教你一招
- android studio计时器怎么用,android - Android Studio:启动倒数计时器时应用崩溃
热门文章
- OpenVz Centos4 Oracle 10g VE
- oracle DBTIMEZONE时区调整
- C程序设计--指针(对 “ 多维数组 ” 进行输出操作)
- 数据库删除表中多列语法总结
- nyoj 1172 unlucky number
- 服务器位置设置,服务器部署位置
- 录屏软件电脑_电脑录屏用什么软件?电脑录屏软件集锦
- 二叉树的宽度 java_Java语言描述二叉树的深度和宽度
- 机器学习中的混淆矩阵,准确率,精确率,召回率,F1,ROC/AUC,AP/MAP
- python中的super用法详解_python中super的用法实例解析