- android中TCP建立連接和通信的方式
接下來(lái)主要介紹下Android中TCP建立連接靴庆,數(shù)據(jù)讀寫(xiě)的基本方法时捌。先創(chuàng)建SocketChannel,SocketChannel設(shè)置成非阻塞式的撒穷,接著創(chuàng)建Selector匣椰,然后將Selector注冊(cè)到SocketChanel中,Android中使用Selector主要是因?yàn)樗且粋€(gè)可以檢測(cè)一個(gè)或多個(gè)Channel并且能夠知道Channel的讀寫(xiě)狀態(tài)的組件端礼,通過(guò)這種方式禽笑,一個(gè)線(xiàn)程可以管理多個(gè)Channel,從而管理這個(gè)網(wǎng)絡(luò)連接蛤奥。
- 首先佳镜,創(chuàng)建SocketChannel和Selector,將Selector注冊(cè)到SocketChannel中凡桥,并向服務(wù)器發(fā)起連接
SocketChannel用于TCP網(wǎng)絡(luò)連接的通道蟀伸,類(lèi)似于非阻塞的Socket。它可以通過(guò)以下兩種方式創(chuàng)建:
- 通過(guò) SocketChannel 的open()方法缅刽,并 connect 網(wǎng)絡(luò)上的服務(wù)器
- 當(dāng) ServerSocketChannel 連接到一個(gè)請(qǐng)求啊掏,也會(huì)創(chuàng)建 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));
- 其次衰猛,建立連接后通過(guò)Selector的select方法獲取就緒的channel迟蜜,進(jìn)行數(shù)據(jù)的讀寫(xiě)操作。
當(dāng)調(diào)用Selector的select()方法且有返回一個(gè)或多個(gè)就緒的channel啡省,就可以使用selector的selectionKey集合了娜睛。像這樣:
Set<SelectionKey> selectedKeys = selector.selectedKeys();
當(dāng)獲取到上面所示的selectedKeys集合,就可以遍歷這個(gè)已選擇的鍵集合來(lái)訪(fǎng)問(wèn)就緒的通道卦睹。如下:
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 移除實(shí)例畦戒,不然下次事件過(guò)來(lái)就接收不到了
keyIterator.remove();
}
這個(gè)循環(huán)遍歷已選擇鍵集中的每個(gè)鍵,并檢測(cè)各個(gè)鍵所對(duì)應(yīng)的通道的就緒事件结序。
注意每次迭代末尾的keyIterator.remove()調(diào)用障斋。Selector不會(huì)自己從已選擇鍵集中移除SelectionKey實(shí)例。必須在處理完通道時(shí)自己移除徐鹤。下次該通道變成就緒時(shí)垃环,Selector會(huì)再次將其放入已選擇鍵集中。
- 關(guān)閉連接
mSocketChanel.close();
mSelector.close();
當(dāng)使用完selector凳干,可以調(diào)用SocketChannel和Selector的close方法晴裹,這樣就完成TCP連接的釋放。