Netty的深入浅出--35.零拷贝实例剖析

下面写两个程序一个基于IO的,一个基于NIO的。将两个进行对比看出优劣;

对比方法:客户端不断的从磁盘中读取数据到服务端,服务端收到数据之后丢弃。最后对比两种方式所消耗的时间。

IO操作:

服务端:

客户端:

 启动服务端:

启动客户端:

运行很多次之后,发现耗时基本上停留在400多毫秒

 

NIO:

服务端:

这里设置了一个socket属性:

我们查看一下它的源码 的dom说明:

该方法是禁用或者启动SocketOptions这个属性

描述的是:在连接关闭之后,但是tcp连接可能处于的是一种超时的状态,这种状态称为一种time_wait状态

 当处于上面所说的time_wait之后,是不能绑定到这个socke端口号上的。一但尝试绑定就会报这个地址已经被占用的警告。因为虽然断开了连接,但是还是只是处于一种超时的状态,没有释放掉这个socket端口号,简单来说就是:占着坑位,不过干事。

 所以说,当我们使用了setreuseaddress方法之后,我们就可以使用这种处于time_out状态下的端口号了

当连接上之后会获得一个通道:

accept方法的dom源码:

如果是非阻塞的话,在未连接的情况下返回时null

如果是阻塞的话,在未连接的情况下会一直阻塞式等待连接

不过它返回的socket方法,一定是阻塞模式的

它默认情况下都是阻塞的,如果我们不设置其实也是可以的,但是如果有selector的话,一定要使用非阻塞的。

 将数据读到bytebuffer当中:

现在我们需要重新将bytebuffer的position和limit位置回到初始位(之前我们采用的是clear或者flip两种方式):

查看rewind方法源码:

客户端:

获取socketChannel对象

向服务器端发起连接:

 

 在之前使用selector管理channel的时候,我们设置的是非阻塞的,现在由于只有一个客户端,而且并没有使用selector,所以我们直接使用阻塞式就可以了

获取文件通道

 

第一个方法transferFrom:将数据读到channel通道中来

第二个方法transferTo:将数据写到writeByteChannel中去;

 

 然后传递到socketChannel;

返回的是实际传递的数量

 查看transferTo方法源码:

将传递的字节放入到能够写的byte channel中

 如果采用的是非阻塞的形式的话,读取的字节数量会相比更少:

重点:这个方法比我们之前使用循环不断从filechannel中读取数据效率更高 !

重点:在一些操作系统中直接将字节传送到文件系统缓存中,而不是去先将他们复制一份。这就是之前说的零拷贝。

 

打印:

 

启动服务器:

 

启动客户端:

 

 对比之前IO耗时,发现性能上效率上提高了很多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值