1 packageorg.windwant.nio;2
3 importjava.io.IOException;4 importjava.net.InetSocketAddress;5 importjava.net.ServerSocket;6 importjava.nio.ByteBuffer;7 importjava.nio.channels.SelectionKey;8 importjava.nio.channels.Selector;9 importjava.nio.channels.ServerSocketChannel;10 importjava.nio.channels.SocketChannel;11 importjava.util.Iterator;12 importjava.util.Set;13
14 /**
15 * ServerSocketChannel16 */
17 public classNIOServer {18 /*标识数字*/
19 private int flag = 0;20 /*缓冲区大小*/
21 private int BLOCK = 2048;22 /*接受数据缓冲区*/
23 private ByteBuffer sendbuffer =ByteBuffer.allocate(BLOCK);24 /*发送数据缓冲区*/
25 private ByteBuffer receivebuffer =ByteBuffer.allocate(BLOCK);26 privateSelector selector;27
28 public NIOServer(int port) throwsIOException {29 //打开服务器套接字通道
30
31 ServerSocketChannel serverSocketChannel =ServerSocketChannel.open();32 //服务器配置为非阻塞
33
34 serverSocketChannel.configureBlocking(false);35 //检索与此通道关联的服务器套接字
36
37 ServerSocket serverSocket =serverSocketChannel.socket();38 //进行服务的绑定
39
40 serverSocket.bind(newInetSocketAddress(port));41 //通过open()方法找到Selector
42
43 selector =Selector.open();44 //注册到selector,等待连接
45
46 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);47 System.out.println("Server Start----8888:");48 }49
50
51 //监听
52
53 private void listen() throwsIOException {54 while (true) {55 //选择一组键,并且相应的通道已经打开
56
57 selector.select();58 //返回此选择器的已选择键集。
59
60 Set selectionKeys =selector.selectedKeys();61 Iterator iterator =selectionKeys.iterator();62 while(iterator.hasNext()) {63 SelectionKey selectionKey =iterator.next();64 iterator.remove();65 handleKey(selectionKey);66 }67 }68 }69
70 //处理请求
71
72 private void handleKey(SelectionKey selectionKey) throwsIOException {73 //接受请求
74
75 ServerSocketChannel server = null;76 SocketChannel client = null;77 String receiveText;78 String sendText;79 int count=0;80 //测试此键的通道是否已准备好接受新的套接字连接。
81
82 if(selectionKey.isAcceptable()) {83 //返回为之创建此键的通道。
84
85 server =(ServerSocketChannel) selectionKey.channel();86 //接受到此通道套接字的连接。87
88 //此方法返回的套接字通道(如果有)将处于阻塞模式。
89
90 client =server.accept();91 //配置为非阻塞
92
93 client.configureBlocking(false);94 //注册到selector,等待连接
95
96 client.register(selector, SelectionKey.OP_READ);97 } else if(selectionKey.isReadable()) {98 //返回为之创建此键的通道。
99
100 client =(SocketChannel) selectionKey.channel();101 //将缓冲区清空以备下次读取
102
103 receivebuffer.clear();104 //读取服务器发送来的数据到缓冲区中
105
106 count =client.read(receivebuffer);107 if (count > 0) {108 receiveText = new String( receivebuffer.array(),0,count);109 System.out.println("服务器端接受客户端数据--:"+receiveText);110 client.register(selector, SelectionKey.OP_WRITE);111 }112 } else if(selectionKey.isWritable()) {113 //将缓冲区清空以备下次写入
114
115 sendbuffer.clear();116 //返回为之创建此键的通道。
117
118 client =(SocketChannel) selectionKey.channel();119
120
121 sendText = "
message from server: this is the test message!
";122123 //sendText="message from server--" + flag++;124 //向缓冲区中输入数据
125
126 sendbuffer.put(sendText.getBytes());127 //将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位
128
129 sendbuffer.flip();130 //输出到通道
131
132 client.write(sendbuffer);133 System.out.println("服务器端向客户端发送数据--:"+sendText);134 client.register(selector, SelectionKey.OP_READ);135 }136 }137
138 /**
139 *@paramargs140 *@throwsIOException141 */
142 public static void main(String[] args) throwsIOException {143 int port = 8888;144 NIOServer server = newNIOServer(port);145 server.listen();146 }147 }