- android中TCP建立连接和通信的方式
接下来主要介绍下Android中TCP建立连接,数据读写的基本方法。先创建SocketChannel,SocketChannel设置成非阻塞式的,接着创建Selector,然后将Selector注册到SocketChanel中,Android中使用Selector主要是因为它是一个可以检测一个或多个Channel并且能够知道Channel的读写状态的组件,通过这种方式,一个线程可以管理多个Channel,从而管理这个网络连接。
- 首先,创建SocketChannel和Selector,将Selector注册到SocketChannel中,并向服务器发起连接
SocketChannel用于TCP网络连接的通道,类似于非阻塞的Socket。它可以通过以下两种方式创建:
- 通过 SocketChannel 的open()方法,并 connect 网络上的服务器
- 当 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连接的释放。
网友评论