NIO-02

作者: 平头哥2 | 来源:发表于2020-08-17 14:10 被阅读0次

    server

    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectableChannel;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Iterator;
    import java.util.Set;
    
    public class NIOServer {
    
        public static void main(String[] args) throws Exception {
            // 1. 获取 ServerSocketChannel
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    
            // 2. 获取 Selector 对象
            Selector selector = Selector.open();
    
            // 3. 绑定一个 ip 和 端口 6666, 在服务器端监听
            serverSocketChannel.socket().bind(new InetSocketAddress(6666));
    
            // 4. 设置为非阻塞
            serverSocketChannel.configureBlocking(false);
    
            // 5. 把 serverSocketChannel 注册到 selector 关心, 事件为 OP_ACCEPT
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    
            // 6. 循环等待客户端链接
            while (true) {
    
                // eg: 这里我们等待1秒,如果没有事件发生,就返回
    
                if (selector.select(1000) == 0) {// eg: 没有事件发生
                    System.out.println("服务器等待了1秒, 无链接");
                    continue;
                }
    
                // eg: 如果返回的 大于0
                // eg: 该集合是表示有 事件发生的集合
                Set<SelectionKey> selectedKeys = selector.selectedKeys();
                // eg: 通过 selectedKeys 可以反向获取 channel
    
                Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
                while (keyIterator.hasNext()) {
                    SelectionKey selectionKey = keyIterator.next();
                    if (selectionKey.isAcceptable()) {
                        // accept() 是阻塞的,但是这里不会阻塞
                        SocketChannel socketChannel = serverSocketChannel.accept();
                        socketChannel.configureBlocking(false);
                        // eg: 将 socketChannel 注册到 selector 上, 关注只读事件,关联一个 ByteBuffer
                        socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                    }
    
                    if (selectionKey.isReadable()) {
                        // eg: 通过key 反向获取channel
                        SocketChannel channel = (SocketChannel) selectionKey.channel();
                        ByteBuffer attachment = (ByteBuffer) selectionKey.attachment();
                        int read = channel.read(attachment);
                        
                        System.out.println("客户端发送来的数据:"+new String(attachment.array(),0, attachment.position()));
                        
                    }
                    // eg: 手动从集合中移除 selectionKey, 防止重复提交
                    // selectedKeys.remove(selectionKey); 并发修改异常
                    keyIterator.remove();
                }
            }
    
        }
    
    }
    

    client

    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.SocketChannel;
    
    public class NIOClient {
    
        public static void main(String[] args) throws Exception {
            // 1: 客户端通道
            SocketChannel socketChannel = SocketChannel.open();
            
            //2. 设置为非阻塞
            socketChannel.configureBlocking(false);
            
            //3. 链接服务器
            InetSocketAddress inetSocketAddress = new InetSocketAddress("localhost", 6666);
            
            //4. 链接
            if(!socketChannel.connect(inetSocketAddress)) {
                while (! socketChannel.finishConnect()) {
                    System.out.println("客户端链接需要时间...");
                    
                }
            }
            //4.1 如果链接成功,发送数据
            String content = "helloworld";
            ByteBuffer buffer = ByteBuffer.wrap(content.getBytes());
            
            socketChannel.write(buffer);
            
            //System.in.read();
            
        }
    }
    

    相关文章

      网友评论

          本文标题:NIO-02

          本文链接:https://www.haomeiwen.com/subject/kzhqjktx.html