JAVA中Sockets长连接时使用read()阻塞的问题!急救!

oppo_2010 2013-10-24 12:10:17
这个问题纠结了我一天了,怎么也没有解决。希望谁能帮帮我!
就是从服务端接收数据,客户端向服务度发送数据,然后服务端返回一条语句可以正常接收;
代码:
datas = new String(datas.getBytes("GB2312"),"8859_1");
dos.writeBytes(datas);
byte[] buf = new byte[512];
InputStream inputStream = socket.getInputStream();
int ret = inputStream.read(buf);
strRecvData = new String(buf, "GB2312").trim();
但当服务端返回多条数据时,如服务端处理客户端发来的数据,处理2s后发送返回给客户端,inputStream.read(buf);就直接阻塞无响应了。查了很多方法,比如写入一个循环中和单独的线程中。仍然无法实现。代码如下:
while (true) {
try {
byte buff[] = new byte[500];// 缓冲数组
if (buff != null && buff.length > 0) {
inputStream.read(buff);
String str = new String(buf, "GB2312").trim();// 接受客户端发送的数据包

catch (IOException ioe) {
System.out.println("读写异常:"+ioe.getMessage());
}
}
还有这种方法,代码如下:
byte[] buf = new byte[512];
int n=0;
while( (n=inputStream.read(buf)) != -1 ) {
//处理buf里的数据
//卡死无响应,不会执行
}
但无论怎样,只要执行inputStream.read(),inputStream.read(buff),就会卡死,阻塞无响应。。即使服务端已经发送完毕了,还是无响应,卡死。
现在有两个疑问,纠结着我:
1:如果服务端没有关闭输出流,一直给我发送数据,这时客户端接收使用inputStream.read()函数,是不是会一直阻塞,直到服务端数据全部发送完毕?
2:问题出在哪里啊?代码怎么修改才可以读取到服务端数据,服务端发过来多少数据,我就能接收读取多少数据?


求解!我真想哭了。。。。
...全文
728 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
oppo_2010 2013-10-24
  • 打赏
  • 举报
回复
服务端没有关闭流。。
read()也一直阻塞着。。
我想服务端一边给发送着数据,我一边读取着数据,这应该怎么实现呢?应该用什么方法呢
失落夏天 2013-10-24
  • 打赏
  • 举报
回复
客户端收到多条数据,每次你的is都关闭了么? 我指的是你客户端接收时,服务端是否关闭了流?
xiaomm627 2013-10-24
  • 打赏
  • 举报
回复
这种问题我觉得是这样,客户端接收数据有个缓冲区,你定义的一个buff,并且给定死了大小是512,但是呢你并不知道服务端每次会发送多大的数据过来,在客户端这边如果接收的数据达到512,那么可以正常的接收,如果没有达到512且你服务端的流没有关闭那么它就会阻塞(客户端会认为数据还在传送)。 你可以这样解决,在数据传输时加上一个传输头(socketHeader,一般是个类对象,序列化后把这个对象的字节流发送出去,这个对像可以设置个属性说明接下来要发送的真正数据占多大的空间),客户端接收这个对象的字节流后再把它还原成对象,获取那个属性值,然后你再构造buffer,大小为这个属性值。这样就能保证客户端的buffer每次都会被填充满,自然也就不会阻塞。 不知道我说的这么形象你听明白了没? 以前我也遇到过这种问题,客户端是java,服务端是c++。 当然了,不过客户端和服务端都是java写的,我觉得就没必要这么传输,用readLine最方便,也不用考虑buffer大小。
yao_yao_qiekenao 2013-10-24
  • 打赏
  • 举报
回复
我了解这种情况,一般是在传入参数的时候定义一个结束标签如<end> 服务端read完的时候判断是否接收到了结束标签,或者接收的字符串结尾是否是结束标签<end> 如果是<end>则代表服务端接收参数结束。就不要继续read了,跳出read往下执行直接根据参数执行逻辑 最后返回结果,关闭服务端输入流和输出流。 不知道你明白了吗 千万不要用 read是否返回-1或者==null去判断,在java的socket是阻塞的,是会有问题的
oppo_2010 2013-10-24
  • 打赏
  • 举报
回复
引用 5 楼 szx_zsx 的回复:
socket是阻塞模式的,如果没有消息发送,read这边会一直阻塞的,知道有数据包传过来。你可以在接收端做超时处理,超过多少秒重连服务器。
设置过,但执行read()就会阻塞,然后超时重连,还是阻塞到read(),服务端是别人写的,我问了下,他那边服务端的流是没有关闭过的。。。 怎么才能做到一直监听中,发过来多少数据,我收到多少数据。
赏金--猎人 2013-10-24
  • 打赏
  • 举报
回复
socket是阻塞模式的,如果没有消息发送,read这边会一直阻塞的,知道有数据包传过来。你可以在接收端做超时处理,超过多少秒重连服务器。
oppo_2010 2013-10-24
  • 打赏
  • 举报
回复
引用 3 楼 rumlee 的回复:
服务端flush一下试试看 如果不希望阻塞,建议用nio吧。或者用个mina之类的框架,做起来就简单多了。
服务端的流如果不关闭或者没有flush,是不是read()这边会一直阻塞呢? mina之类的框架使用在Android开发下也是可以的吗?因为程序写在Android程序里的。
rumlee 2013-10-24
  • 打赏
  • 举报
回复
服务端flush一下试试看 如果不希望阻塞,建议用nio吧。或者用个mina之类的框架,做起来就简单多了。

62,614

社区成员

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

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