美文网首页
基于NIO的网络框架实现

基于NIO的网络框架实现

作者: Brook_liu | 来源:发表于2021-05-19 20:03 被阅读0次
  • android中TCP建立连接和通信的方式

接下来主要介绍下Android中TCP建立连接,数据读写的基本方法。先创建SocketChannel,SocketChannel设置成非阻塞式的,接着创建Selector,然后将Selector注册到SocketChanel中,Android中使用Selector主要是因为它是一个可以检测一个或多个Channel并且能够知道Channel的读写状态的组件,通过这种方式,一个线程可以管理多个Channel,从而管理这个网络连接。

  • 首先,创建SocketChannel和Selector,将Selector注册到SocketChannel中,并向服务器发起连接

SocketChannel用于TCP网络连接的通道,类似于非阻塞的Socket。它可以通过以下两种方式创建:

  1. 通过 SocketChannel 的open()方法,并 connect 网络上的服务器
  2. 当 ServerSocketChannel 连接到一个请求,也会创建 SocketChannel。
SocketChannel socketChannel = SocketChannel.open();

mSelector = Selector.open();

socketChanel.register(mSelector, SelectionKey.OP_CONNECT);

socketChannel.connect(new  InetSocketAddress("[http://jenkov.com](http://jenkov.com/)", 80));
  • 其次,建立连接后通过Selector的select方法获取就绪的channel,进行数据的读写操作。

当调用Selector的select()方法且有返回一个或多个就绪的channel,就可以使用selector的selectionKey集合了。像这样:

Set<SelectionKey> selectedKeys = selector.selectedKeys();

当获取到上面所示的selectedKeys集合,就可以遍历这个已选择的键集合来访问就绪的通道。如下:

Set<SelectionKey> selectedKeys = selector.selectedKeys();

Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

while (keyIterator.hasNext()) {

SelectionKey key = keyIterator.next();

if(key.isAcceptable()) {

// a connection was accepted by a ServerSocketChannel.

} else if (key.isConnectable()) {

// a connection was established with a remote server.

} else if (key.isReadable()) {

// a channel is ready for reading

} else if (key.isWritable()) {

// a channel is ready for writing

}

// 记得要 remove 移除实例,不然下次事件过来就接收不到了

keyIterator.remove();

}

这个循环遍历已选择键集中的每个键,并检测各个键所对应的通道的就绪事件。

注意每次迭代末尾的keyIterator.remove()调用。Selector不会自己从已选择键集中移除SelectionKey实例。必须在处理完通道时自己移除。下次该通道变成就绪时,Selector会再次将其放入已选择键集中。

  • 关闭连接
mSocketChanel.close();

mSelector.close();

当使用完selector,可以调用SocketChannel和Selector的close方法,这样就完成TCP连接的释放。

相关文章

网友评论

      本文标题:基于NIO的网络框架实现

      本文链接:https://www.haomeiwen.com/subject/wgqmjltx.html