java socket read阻塞问题解决!

一个人喝不醉 2017-03-31 05:47:33
需求:需要做一个长连接通信项目的服务端,客户端不是我做的,而且客户端每次发来的数据包长度无法固定,针对客户端发来的数据包解析后需要查询具体数据给之回应,客户端收到回应后再发送一个确认包给包,我再写入日志表示完成了一个完整的请求;
困惑:我在服务端使用serverSocket.accept()监听到一个具体的客户端后与之进行开辟一个单独的线程进行通信,但是我再服务端中调用了socket提供的输入流中的read函数socket.getInputStream.read(),这个函数会有阻塞现象,一直无穷无尽的在哪读,没有数据的时候就阻塞,代码死活不往下走,由于客户端那边无法提供每次发送的包大小,我这边很能完整的判断一个请求是否完毕,闹心啊;
...全文
588 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
火灵 2017-04-07
  • 打赏
  • 举报
回复
肯定有通信协议啊,你们公司自定义的或用某些公开的
FengRider 2017-04-07
  • 打赏
  • 举报
回复
在约定了数据交互的格式后,可以忽略每次数据传输一定要报数据大小。服务器和客户端直接根据数据格式来解析。举个最简单的例子: socket服务器是TELNET或者SSH的客户端,通过TELNET或者SSH协议登录到一台LINUX系统,执行一条命令,然后将LINUX执行命令返回的结果再返回给客户端,不同的LINUX命令,返回的结果集肯定是不定长的。但是有一点可以肯定。LINUX的每一条命令,最后都是以命令提示符结尾,或者是'$',或者是'#',或者是'>'。那么socket服务器在大体原则上是根据最后一个字符是否是命令提示符来判断是否已经收集完当前这次所有的数据了。 当然,这仅仅只是一个大概是否收集完全。实际操作过程中,数据格式约定的越细致,数据越容易解析。比如一次完整的数据包,以什么字符开始,以什么字符结束。中间的数据值是按json或者xml或者name=value$$name2=value2这种格式来传送。
tianfang 2017-04-07
  • 打赏
  • 举报
回复
不定长可以约定放在一个tcp包中,信息头部(不是tcp包头)应该有自定义的标识 使用异步框架read由框架处理好,生成消息,你直接写消息处理就是了
tianfang 2017-04-07
  • 打赏
  • 举报
回复
三个问题: 1 由于客户端那边无法提供每次发送的包大小,我这边很能完整的判断一个请求是否完毕 这是协议定义不完全, 不定长数据的必须先传输长度 2 不同状态下的处理方式 参考设计模式的状态模式,http://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/state.html 3 开发问题 长连接开发最好使用异步框架来做,会方便很多,如netty,从例子修改一下就可以了
FengRider 2017-04-07
  • 打赏
  • 举报
回复
事实上,不仅服务端需要这样监听,客户端也需要这样监听数据流,如果服务端和客户端不提前约定好数据传输格式,双方在接受数据过程就无从判断一次数据传送什么时候真正的完成。
FengRider 2017-04-07
  • 打赏
  • 举报
回复
收到客户端的数据,总是要做点事的吧。所以仅凭socket还不够,还得与客户端约定好数据的传入格式,即自定义一种数据协议,这样才能够确定客户端一次提交过来的数据到底是什么。如果不定这个协议,网络的通畅与否会让服务端完全蒙圈。虽然输入流对象里面有方法可以事先判断一下客户端这次发过来的数据包大小,比如:

InputStream in = socket.getInputStream;
int dataNum = in.available();
但这受限于网络,并不一定是客户端真正过来的一个完整的数据包。仅只是在目前网络堵塞状况允许的情况下,发过来的一个数据包的数据大小而已。所以,必须得为客户端启用一个线程,不停的从客户端读数据,当服务端与客户端的通信结束时,再通知这个线程结束。在这个线程内,需要时刻监听客户端是否有数据发送过来。服务端再根据约定,将读过来的数据进行解析。
qq_32295869 2017-03-31
  • 打赏
  • 举报
回复
不知道你表达的什么意思,你开辟线程读出来请求就行了,在下面进行处理就行了啊,他这个本来就是阻塞,

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧