work hard work smart

专注于Java后端开发。 不断总结,举一反三。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

NIO网络编程

Posted on 2019-08-17 16:27  work hard work smart  阅读(173)  评论(0编辑  收藏  举报

1、创建服务端代码

public class NioServer {

    private static Map<String, SocketChannel> clientMap = new HashMap<>();

    public static void main(String[] args) throws IOException {

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        ServerSocket serverSocket = serverSocketChannel.socket();
        serverSocket.bind(new InetSocketAddress(8899));

        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true){
            try {
                selector.select();
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                selectionKeys.forEach( selectionKey -> {

                    final SocketChannel  client;
                    try{
                        //客户端向服务端发起一个连接
                        if(selectionKey.isAcceptable()){
                            ServerSocketChannel server = (ServerSocketChannel)selectionKey.channel();
                            client = server.accept();
                            client.configureBlocking(false);
                            client.register(selector, SelectionKey.OP_READ);
                            String key = "[" +  UUID.randomUUID() + "]";
                            clientMap.put(key, client);

                        }
                        //有数据可读
                        else if(selectionKey.isReadable()){
                            client = (SocketChannel)selectionKey.channel();
                            ByteBuffer readBuffer = ByteBuffer.allocate(1024);
                            int count = client.read(readBuffer);
                            if(count > 0){
                                readBuffer.flip();

                                Charset charset = Charset.forName("utf-8");

                                String receivedMessage = String.valueOf(charset.decode(readBuffer).array());

                                System.out.println(client + ": " + receivedMessage);

                                String senderKey = null;

                                for(Map.Entry<String,SocketChannel> entry : clientMap.entrySet()){
                                    if(client == entry.getValue()){
                                        senderKey = entry.getKey();
                                        break;
                                    }
                                }

                                for(Map.Entry<String,SocketChannel> entry : clientMap.entrySet()){
                                    SocketChannel value = entry.getValue();
                                    ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
                                    writeBuffer.put((senderKey + ":" + receivedMessage).getBytes());
                                    writeBuffer.flip();
                                    value.write(writeBuffer);
                                }

                            }
                        }
                    }catch (Exception ex){
                        ex.printStackTrace();
                    }
                });


                selectionKeys.clear();

            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
        

    }
}

  

2、创建客户端代码

public class NioClient {

    public static void main(String[] args) {
        try{

            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.configureBlocking(false);

            Selector selector = Selector.open();
            socketChannel.register(selector, SelectionKey.OP_CONNECT);

            socketChannel.connect(new InetSocketAddress("127.0.0.1",8899));

            while (true){
                selector.select();
                Set<SelectionKey> keySet = selector.selectedKeys();

                for(SelectionKey selectionKey : keySet){
                    //与服务端已经建立好了连接
                    if(selectionKey.isConnectable()){
                        SocketChannel client = (SocketChannel)selectionKey.channel();
                        if(client.isConnectionPending()){
                            client.finishConnect();
                            //向服务端发数据
                            ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
                            writeBuffer.put((LocalDateTime.now() + "连接成功").getBytes());
                            writeBuffer.flip();
                            client.write(writeBuffer);

                            //  启动一个线程,不断的读取标准输入的内容。然后将内容向回个服务端
                            ExecutorService executorService = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
                            executorService.submit(() -> {
                                while (true){

                                    try {
                                        writeBuffer.clear();
                                        InputStreamReader input = new InputStreamReader(System.in);
                                        BufferedReader br = new BufferedReader(input);

                                        String sendMessage = br.readLine();

                                        writeBuffer.put(sendMessage.getBytes());
                                        writeBuffer.flip();
                                        client.write(writeBuffer);

                                    }catch (Exception ex){

                                        ex.printStackTrace();
                                    }
                                }
                            });

                        }
                        client.register(selector, SelectionKey.OP_READ);
                    }else if(selectionKey.isReadable()){
                        SocketChannel client = (SocketChannel)selectionKey.channel();
                        ByteBuffer readBuffer = ByteBuffer.allocate(1024);

                        int count = client.read(readBuffer);

                        if(count > 0){
                            String receivedMessage = new String(readBuffer.array(), 0, count);
                            System.out.println(receivedMessage);
                        }

                    }
                }
                keySet.clear();
            }

        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}

  

3、测试

1) 启动服务端

2) 启动两个客户端

3) 输出结果

NioServer输出

 

第一个NioClient输出。连接建立后,输入hello

 

第二个NioClient输出。 连接建立后,输入world