java selector


java selector使用select輪詢注冊到selector中的channel,如果有channel准備好注冊的事件,select()返回,返回值為可以操作的channel的個數。通過selector.selectedKeys()返回選中的key的集合。遍歷集合中所有的key,判斷key的事件,進行相應的處理,並從集合中remove掉。

客戶端selector的使用邏輯與服務端selector使用邏輯幾乎一致。

Server代碼中監聽了兩個端口8888和8889兩個端口,並注冊到selector中。讀取客戶端發送的信息,並發送信息到客戶端

Client代碼向服務器對應的端口號發送信息,並接收服務器端返回的信息

這里我服務端用了channel+selector客戶端直接用的socket,可以發送給服務端信息,但接收服務端信息沒有接收到(代碼沒有貼出來)

 

PS:使用selector+channel可以在一個線程內監聽多個channel,下面代碼中就監聽了兩個端口的channel

 

SelectorServer.java

  1 import java.io.IOException;
  2 import java.net.InetSocketAddress;
  3 import java.net.ServerSocket;
  4 import java.nio.ByteBuffer;
  5 import java.nio.channels.SelectionKey;
  6 import java.nio.channels.Selector;
  7 import java.nio.channels.ServerSocketChannel;
  8 import java.nio.channels.SocketChannel;
  9 import java.util.Iterator;
 10 import java.util.Set;
 11 
 12 /**
 13  * Created by 58 on 2016/11/28.
 14  */
 15 public class SelectorServer {
 16     public static void main(String args[]){
 17         startServer();
 18     }
 19     public static ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
 20     public static ByteBuffer receiveBuffer = ByteBuffer.allocate(1024);
 21 
 22     public static void startServer(){
 23         //用兩個channel監聽兩個端口
 24         int listenPort = 8888;
 25         int listenPort1 = 8889;
 26         sendBuffer.put("message from server".getBytes());
 27 
 28         try {
 29             //創建serverchannel,綁定對應的端口
 30             ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
 31             ServerSocket serverSocket = serverSocketChannel.socket();
 32             InetSocketAddress inetSocketAddress = new InetSocketAddress(listenPort);
 33             serverSocket.bind(inetSocketAddress);
 34 
 35             //創建第二個channel
 36             ServerSocketChannel serverSocketChannel1 = ServerSocketChannel.open();
 37             ServerSocket serverSocket1 = serverSocketChannel1.socket();
 38             InetSocketAddress inetSocketAddress1 = new InetSocketAddress(listenPort1);
 39             serverSocket1.bind(inetSocketAddress1);
 40 
 41 
 42             //創建selector對象
 43             Selector selector = Selector.open();
 44 
 45             //設置channel注冊到selector中
 46             serverSocketChannel.configureBlocking(false);
 47             serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
 48 
 49             //第二個channel
 50             serverSocketChannel1.configureBlocking(false);
 51             serverSocketChannel1.register(selector, SelectionKey.OP_ACCEPT);
 52 
 53             System.out.println("start to listen port: " + listenPort);
 54             System.out.println("start to listen port: " + listenPort1);
 55 
 56             //監聽端口
 57             while(true){
 58                 int readyChannels = selector.select();
 59                 if(readyChannels == 0)
 60                     continue;
 61                 Set<SelectionKey> selectedKeys = selector.selectedKeys();
 62                 Iterator<SelectionKey> iterator = selectedKeys.iterator();
 63                 while(iterator.hasNext()){
 64                     SelectionKey selectionKey = iterator.next();
 65                     dealSelectionKey(selector, selectionKey);
 66 
 67                     iterator.remove();
 68                 }//while
 69             }//while
 70 
 71 
 72         } catch (IOException e) {
 73             e.printStackTrace();
 74         }
 75     }
 76 
 77     public static void dealSelectionKey(Selector selector, SelectionKey selectionKey){
 78         try{
 79             //准備好接收新的連接
 80             if(selectionKey.isAcceptable()){
 81                 ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
 82                 SocketChannel clientSocketChannel = serverSocketChannel.accept();
 83                 clientSocketChannel.configureBlocking(false);
 84                 clientSocketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
 85                 System.out.println("channel is ready acceptable");
 86             }
 87             else if(selectionKey.isConnectable()){
 88                 selectionKey.channel().register(selector, SelectionKey.OP_READ);
 89                 System.out.println("channel is connectable.");
 90             }
 91             else if(selectionKey.isReadable()){
 92                 //讀去客戶端內容
 93                 SocketChannel clientSocketChannel = (SocketChannel) selectionKey.channel();
 94                 receiveBuffer.clear();
 95                 clientSocketChannel.read(receiveBuffer);
 96                 selectionKey.interestOps(SelectionKey.OP_WRITE);
 97                 System.out.println("message from client is: " + new String(receiveBuffer.array()));
 98                 System.out.println("Thread id : " + Thread.currentThread().getId());
 99             }
100             else if(selectionKey.isWritable()){
101                 //向客戶端寫數據
102                 SocketChannel clientSocketChannel = (SocketChannel) selectionKey.channel();
103                 sendBuffer.flip();
104                 System.out.println("sendBuffer = " + new String(sendBuffer.array()));
105                 clientSocketChannel.write(sendBuffer);
106                 selectionKey.interestOps(SelectionKey.OP_READ);
107                 System.out.println("channle is writable.");
108             }//else if
109         }catch (Exception e){
110 
111         }
112     }
113 }

SelectorClient.java

 1 import java.io.IOException;
 2 import java.net.InetSocketAddress;
 3 import java.nio.ByteBuffer;
 4 import java.nio.channels.SelectionKey;
 5 import java.nio.channels.Selector;
 6 import java.nio.channels.SocketChannel;
 7 import java.util.Iterator;
 8 import java.util.Set;
 9 
10 /**
11  * Created by 58 on 2016/11/28.
12  */
13 public class SelectorClient {
14     public static void main(String args[]){
15         work();
16     }
17 
18     public static void work(){
19         int serverPort = 8888;
20         ByteBuffer sendBuffer = ByteBuffer.wrap("client message".getBytes());
21         ByteBuffer receiveBuffer = ByteBuffer.allocate(1024);
22         try {
23             //創建通道,設置通道注冊到selector中
24             SocketChannel socketChannel = SocketChannel.open();
25             Selector selector = Selector.open();
26 
27             socketChannel.configureBlocking(false);
28             socketChannel.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ | SelectionKey.OP_CONNECT);
29             socketChannel.connect(new InetSocketAddress("localhost", serverPort));
30             int executeTimes = 2;
31             //while
32             while(executeTimes > 0){
33                 executeTimes--;
34                 int reayChannelNum = selector.select();
35                 if(reayChannelNum == 0){
36                     continue;
37                 }
38                 Set<SelectionKey> setOfSelectionKey = selector.selectedKeys();
39                 Iterator<SelectionKey> iterator = setOfSelectionKey.iterator();
40                 while(iterator.hasNext()){
41                     SelectionKey selectionKey = iterator.next();
42                     SocketChannel socketChannel1 = (SocketChannel) selectionKey.channel();
43                     iterator.remove();
44                     if(selectionKey.isConnectable()){
45                         if(socketChannel1.isConnectionPending()){
46                             socketChannel1.finishConnect();
47                             System.out.println("connection complete.");
48                             socketChannel1.write(sendBuffer);
49                         }
50                     }//if isConnectable
51                     else if(selectionKey.isReadable()){
52                         receiveBuffer.clear();
53                         socketChannel1.read(receiveBuffer);
54                         receiveBuffer.flip();
55                         System.out.println("message from server: " + new String(receiveBuffer.array()));
56 
57                     }//else if readable
58                     else if(selectionKey.isWritable()){
59                         sendBuffer.flip();
60                         socketChannel1.write(sendBuffer);
61                     }
62                 }
63             }
64         } catch (IOException e) {
65             e.printStackTrace();
66         }
67     }
68 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM