评论不了,所以写成博客,仅供参考
遇到的问题:NIO 非阻塞socket通信时(服务器向客户端响应大文件时,服务器还在不停读取数据,客户端就已经先读完数据了,结束了循环),发现有时候服务器端发送的文件客户端只接受到一部分。
原因:可能是因为非阻塞的原因,只要通道内有数据时,客户端就会开始循环接受,但是服务器可能写数据慢了一步,客户端发现读取完毕了,就退出循环了
解决方法:在外部套了一个死循环,多读几遍
带来的问题:客户端收完数据一直退出不了了
尝试解决的代码如下:
思路:做了一回二次判断,中间间隔了一部分时间,如果两次同时都返回-1,可能真的没数据了,就修改标志退出循环,但是我是单机测试,传2G电影时100毫秒没出什么问题,但不代表没有bug,希望大牛们多多指教,有更好的方法大家共享一下。
//由于读写速度可能不一致,所以轮询多读几遍,但是现在找不到方法退出轮询
boolean flag2 = true;while (flag2) {
int len = 0;
//这个channel是获取的SocketChannel,是服务器往客户端写过来数据的通道
while((len = channel.read(buf)) > 0 ){
System.out.println("正在写"+len);
buf.flip();
//这个fileChannel用来往硬盘中写数据
fileChannel.write(buf);
buf.clear();
}
//这里是二次判断,如果两次都是-1,可能就是没再传回来数据了,修改标志,跳出循环
if(channel.read(buf) == -1) {
Thread.sleep(100);
if(channel.read(buf) == -1) {
flag2 = false;
}
}
}
在写这篇blog 的时候,发现读不到数据返回0,读取完毕返回-1,其实没必要死循环,只需要将>0改为 != -1即可,
不知道网上为什么很多人都写成 >0 ,有什么理由请大牛告知
这里使用 != -1,效果很好,自己挖坑自己跳,以后再也不 >0 了
int len = 0;
//这个channel是获取的SocketChannel,是服务器往客户端写过来数据的通道
while((len = channel.read(buf)) != -1 ){
System.out.println("正在写"+len);
buf.flip();
//这个fileChannel用来往硬盘中写数据
fileChannel.write(buf);
buf.clear();
}