MyMusic问题小结(二)

1、上次小结中遇到了尴尬的filp问题,而且自己要写很多维护网络的代码,最后决定改用netty库。而Netty库的介绍就说,本库的ByteBuf不需要flip,而且可以和ByteBuffer直接转换。具体用法另开一篇,这里简单说一下netty的特点:①异步非阻塞,也就是reactor模式,也就是基于事件驱动;②基于Future的模式,每一个操作都会返回一个ChannelFuture,比如write、read、connect等,在ChannelFuture中可以添加监听器来监听任务是否执行完成,也可以像普通Future那样轮询isXXX;③通过ChannelFuture的sync也可以达到任务同步阻塞完成的效果,这在需要任务顺序执行中比较有用;④netty底层使用的是NIO接口,所以使用了很多NIO中channel的概念和功能。

2、使用Netty时,发现NIO的channel相当强大。在NIO2中,所有的通道都统一描述为channel,包括socket,文件等,都有自己的channel,而这些channel之间是可以直接通过write/read进行数据交换的,换句话说:如果想进行文件传输,不需要自己创建socket并维护传输,只需要把一个可用的socketchannel传递给filechannel.transferTo,即可以实现文件的传输。JavaDoc中也是建议直接使用FileChannel进行文件传输,因为底层实现避免了数据的拷贝,即zero-copy,原理是NIO在底层直接把操作系统中文件系统缓存(如硬盘或内存中)的文件数据写到socket,而不需要应用读取文件内容(即拷贝)再发送,因此加快了文件传输的速度。transferTo返回了每次调用发送的数据量,因此文件较大时,可能需要多次调用transferTo函数(类似于write)。Netty即可以在handler中发送数据,也可以在调用线程中随时用channel发送接收数据。

3、每个客户端需要两个channel,一个消息通信,一个数据传输。消息通信是客户端,数据传输做服务器(下载)或客户端(上传)。从电脑下载歌曲的步骤:①消息channel连接server;②发现下载请求(文件名,文件地址(有默认值),手机上的数据接收服务器IP和port);③server解析请求,连接手机数据接收服务器,成功后开始发送数据。讨论:①本来想在客户端用两个客户端channel去连接server,但是在数据传输的时候,server就需要在已连接的所有channel中去查找该往哪个channel发送数据,如果改为server连接客户端的数据接收服务器,就会简单很多,直接连接就可以发送数据了;②多文件同时下载的时候,可以用多个数据接收服务器接收数据,也可以只用一个数据接收服务器,数据加私有协议标示数据长度,前一种方法简单,但是消耗资源多(线程,端口),后一种方法只需要一个端口一个线程,但是数据量略有增加(加了私有协议),而且要把接收的数据分配到其对应的文件去,相比较下,第二种方法较好,而且增加的分配逻辑也不复杂,另一个好处是,数据传输也可以用私有协议封装,类似于http协议的文件传输(http头+data),还有,第一种方法下服务器需要多个port连接数据接收服务器,相当消耗服务器资源,而后一种方法服务器只需要一个port即可。

你可能感兴趣的:(MyMusic问题小结(二))