关于Java socket读取阻塞解决方法20150731-刘海伦

http://bbs.csdn.net/topics/350227310

2010-12-17 00:43:12
首先,你要仔细看明白read()方法的介绍:
从输入流读取下一个数据字节。返回 0 到 255 范围内的 int 字节值。如果因已到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、检测到流的末尾或者抛出异常前,此方法一直阻塞。
你的流根本就没有到达结尾,read()方法一直阻塞,怎么会返回-1呢?
socket和文件不一样,你从文件中读,读到末尾就到达流的结尾了,所以会返回-1,循环结束
socket如果不关闭的话,你的input会一直等待它发送数据,一直在等,就是所谓的阻塞了。 所以整个程序都阻塞了。
另外caofaping说的“read(byte[] b) 读取最大byte[]的大小的数据,
这里没有阻塞的原因是你只读取byte数组的数据,没有while(true)...”也说明白了为什么你用注释里面的代码不会阻塞的原因。
客户端的代码为什么不会阻塞?因为如果你在服务器端激活注释里面的代码之后,服务器发送一个消息之后就执行finally里面的代码关闭socket了,在客户端就是输入流已经到达结尾了,所以不会阻塞。如果你不用注释里面的代码,服务器端一直在阻塞的,客户端肯定也在阻塞等待。
说了这么多,不知道你明白没有
方法一:(有小bug:数据大小刚好等于这个奇数
private static final int max= 32769;
public void read(InputStream in, int max, boolean isFileStream) throws IOException {
int len = 0;
byte[] temp = new byte[max];
int minLength = isFileStream ? 0 : max;
while(true){
len = in.read(temp);
if(len > 0){
this.append(temp, len);
}

if(len < minLength){
break;
}
}
}
//如果数据大小是偶数,就能被整除,就有bug,32768。破解默认字节数组大小设置为奇数,就不会被整除。(bug:数据大小刚好等于这个奇数)
//文件流返回-1,非文件流阻塞
bc.read(in,false);
方法二:添加结束标志
在服务器端结束的时候给客户端发个消息说明已经结束了..客户端读到这个结束标志的时候也就不要再往文件里面写东西了..也结束..这样你的程序就正确了..
方法三:协议:数据长度+数据




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值