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 }
原文地址:https://www.cnblogs.com/luckygxf/p/6111005.html