客户端
1 public static void main(String[] args) throws IOException { 2 3 4 5 // 创建客户端 6 7 SocketChannel sc = SocketChannel.open(); 8 9 10 11 // 指定要连接的服务器ip和端口 12 13 sc.connect(new InetSocketAddress("127.0.0.1", 9000) ); 14 15 16 17 // 创建缓冲输出 18 19 ByteBuffer buffer = ByteBuffer.allocate(1024); 20 21 22 23 // 给数组添加数据 24 25 buffer.put ("Hi你好啊".getBytes()); 26 27 28 29 // 切换 30 31 buffer.flip(); 32 33 34 35 // 输出数据 36 37 sc.write(buffer); 38 39 40 41 // 关闭资源 42 43 sc.close(); 44 45 }
Demo服务端
1 import java.io.IOException; 2 3 import java.net.InetSocketAddress; 4 5 import java.nio.channels.SelectionKey; 6 7 import java.nio.channels.Selector; 8 9 import java.nio.channels.ServerSocketChannel; 10 11 import java.util.Set; 12 13 14 15 public class Demo服务端 { 16 17 main() throws IOException { 18 19 // 创建服务端对象 20 21 ServerSocketChannel ssc1 = ServerSocketChannel.open(); 22 23 ssc1.bind(new InetSocketAddress(8000)); 24 25 26 27 // 设置非阻塞 28 ssc1.configureBlocking(false); 29 30 // 创建服务器端对象 31 ServerSocketChannel ssc2 = ServerSocketChannel.open(); 32 ssc2.bind(new InetSocketAddress(9000)); 33 ssc2.configureBlocking(false); 34 35 36 37 // 创建服务器端对象 38 ServerSocketChannel ssc3 = ServerSocketChannel.open(); 39 ssc3.bind(new InetSocketAddress(10001)); 40 ssc3.configureBlocking(false); 41 42 43 44 // 创建选择器对象 45 46 Selector s = Selector.open(); 47 48 49 50 // 两个服务器,都要交给选择器来管理 51 52 ssc1.register(s, SelectionKey.OP_ACCEPT); 53 54 ssc2.register(s, SelectionKey.OP_ACCEPT); 55 56 ssc3.register(s, SelectionKey.OP_ACCEPT); 57 58 59 60 // 获取集合 61 // selectedKeys(): 返回集合,集合作用存放的是被连接的服务对象的key 62 Set<SelectionKey> set = s.selectedKeys(); 63 print("集合中元素的个数:" + set.size() ); // 0 (没有服务器被访问的时候,显示0) 64 65 // select(): 这是选择器连接客户端的方法 66 s.select(); 67 68 69 print("集合中元素的个数:" + set.size() ); // 1 (有一个服务端被访问的时候,显示1) 70 71 } 72 73 }
Selector服务端
1 import java.io.IOException; 2 3 import java.net.InetSocketAddress; 4 5 import java.nio.ByteBuffer; 6 7 import java.nio.channels.SelectionKey; 8 9 import java.nio.channels.Selector; 10 11 import java.nio.channels.ServerSocketChannel; 12 13 import java.nio.channels.SocketChannel; 14 15 import java.util.Iterator; 16 17 18 19 public class Selector服务端 { 20 21 main() throws IOException { 22 23 // 1. 获取Selector选择器 24 25 Selector selector = Selector.open(); 26 27 28 29 // 2. 获取通道 30 31 ServerSocketChannel ssc1 = ServerSocketChannel.open(); 32 33 ServerSocketChannel ssc2 = ServerSocketChannel.open(); 34 35 ServerSocketChannel ssc3 = ServerSocketChannel.open(); 36 37 38 39 // 3. 设置为非阻塞 40 41 ssc1.configureBlocking(false); 42 43 ssc2.configureBlocking(false); 44 45 ssc3.configureBlocking(false); 46 47 48 49 // 4.绑定连接 50 51 ssc1.bind (new InetSocketAddress(8000)); 52 53 ssc2.bind (new InetSocketAddress(9000)); 54 55 ssc3.bind (new InetSocketAddress(10000)); 56 57 58 59 // 5.将通道注册到选择器上,并注册的操作为:"接收"操作 60 ssc1.register(selector, SelectionKey.OP_ACCEPT); 61 ssc2.register(selector, SelectionKey.OP_ACCEPT); 62 ssc3.register(selector, SelectionKey.OP_ACCEPT); 63 64 65 // 6.采用轮询的方式,查询获取"准备就绪"的注册过的操作 66 while (selector.select() > 0 ) { 67 68 // 7. 获取当前选择器中,所有的选择键 (“已经准备就绪的操作”) 69 Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator(); 70 while (selectedKeys.hasNext() ){ 71 72 73 74 // 8. 获取"准备就绪"的事件 75 SelectionKey selectedKey = selectedKeys.next(); 76 77 78 // 9. 获取ServerSocketChannel 79 ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectedKey.channel(); 80 81 82 // 10. 接收客户端发来的数据 83 SocketChannel socketChannel = serverSocketChannel.accept(); 84 85 86 // 11. 读取数据 87 ByteBuffer byteBuffer = ByteBuffer.allocate(1024); 88 int length = 0; 89 while ( (length = socketChannel.read(byteBuffer)) != -1 ){ 90 91 byteBuffer.flip(); 92 print (new String(byteBuffer.array(),0,length) ); 93 byteBuffer.clear(); 94 } 95 socketChannel.close(); 96 97 } 98 // 12. 移除选择键 99 selectedKeys.remove(); 100 } 101 // 13. 关闭连接 102 ssc1.close(); 103 ssc2.close(); 104 ssc3.close(); 105 } 106 107 }
图解注释
<1>
<2>
<3>