美文网首页
NIO-03 多人聊天

NIO-03 多人聊天

作者: 平头哥2 | 来源:发表于2020-08-18 08:57 被阅读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 ChatServer {
        // 1. 定义属性
        private Selector selector;
        private ServerSocketChannel serverSocketChannel;
        private static final String HOST = "localhost";
        private static final int PORT = 6667;
    
        public ChatServer() {
    
            try {
                selector = Selector.open();
                serverSocketChannel = ServerSocketChannel.open();
    
                serverSocketChannel.socket().bind(new InetSocketAddress(HOST, PORT));
                serverSocketChannel.configureBlocking(false);
                serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        // eg: 监听
        public void listen() {
    
            try {
    
                while (true) {
    
                    int count = selector.select(2000);
                    if (count > 0) {
                        Set<SelectionKey> selectedKeys = selector.selectedKeys();
    
                        Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
    
                        while (keyIterator.hasNext()) {
                            SelectionKey key = keyIterator.next();
    
                            if (key.isAcceptable()) {
    
                                SocketChannel socketChannel = serverSocketChannel.accept();
                                socketChannel.configureBlocking(false);
                                socketChannel.register(selector, SelectionKey.OP_READ);
    
                                System.out.println(socketChannel.getRemoteAddress() + "....eg: 上线了...");
                            }
    
                            if (key.isReadable()) {// eg: 通道发送read事件
                                // eg: 处理读取
                                System.out.println("处理读数据....");
                                
                                //readData
                                readData(key);
    
                            }
    
                            // eg: 删除当前key
                            keyIterator.remove();
                        }
    
                    } else {
                        System.out.println("等待...");
                    }
                }
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        private void readData(SelectionKey key) {
            SocketChannel socketChannel = null;
            try {
                socketChannel = (SocketChannel) key.channel();
    
                ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    
                int read = socketChannel.read(byteBuffer);
                // eg: 根据 read 读取的数据做
                if (read > 0) {
                    // eg: 把缓存数据转换成字符串
                    String msg = new String(byteBuffer.array());
    
                    System.out.println("from client:" + msg);
    
                    // eg: 向其他客户端转发消息,专门处理
                    sendInfoToOthers(msg,socketChannel);
                }
    
            } catch (Exception e) {
                try {
                    System.out.println(socketChannel.getRemoteAddress()+"下线了...");
                    key.cancel();
                    socketChannel.close();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                
            }
        }
    
        // eg: 向其他客户端转发消息,专门处理
        public void sendInfoToOthers(String msg, SocketChannel self) throws Exception {
            System.out.println("sendInfoToOthers....");
    
            Set<SelectionKey> keys = selector.keys();
            for (SelectionKey selectionKey : keys) {
    
                SelectableChannel channel = selectionKey.channel();
                if (channel instanceof SocketChannel && self != channel) {
                    SocketChannel sc = (SocketChannel) channel;
                    
                    ByteBuffer wrap = ByteBuffer.wrap(msg.getBytes());
                    sc.write(wrap);
                }
            }
        }
    
        public static void main(String[] args) {
            ChatServer server = new ChatServer();
            server.listen();
        }
    }
    

    client

    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.SocketChannel;
    import java.util.Iterator;
    import java.util.Scanner;
    import java.util.Set;
    
    public class ChatClient {
        // 1. 定义属性
        private Selector selector;
        private String username;
        private SocketChannel socketChannel;
        private static final String HOST = "localhost";
        private static final int PORT = 6667;
    
        public ChatClient() {
    
            try {
                selector = Selector.open();
                socketChannel = SocketChannel.open(new InetSocketAddress(HOST, PORT));
                socketChannel.configureBlocking(false);
                socketChannel.register(selector, SelectionKey.OP_READ);
                username = socketChannel.getLocalAddress().toString().substring(1);
                System.out.println("username:" + username);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        //eg: 向服务器发送消息
        public void sendMsg2Server(String info) {
            
            info = username +" : "+ info;   
            try {
                socketChannel.write(ByteBuffer.wrap(info.getBytes()));
            } catch (IOException e) {
                e.printStackTrace();
            }
            
        }
        
        //eg: 读取从服务器回复的消息
        public void readInfo() {
            
            try {
                
                int select = selector.select();
                if(select > 0) {
                    Set<SelectionKey> keys = selector.selectedKeys();
                    Iterator<SelectionKey> iterator = keys.iterator();
                    while (iterator.hasNext()) {
                        SelectionKey selectionKey = iterator.next();
                        if(selectionKey.isReadable()) {
                            SocketChannel channel = (SocketChannel) selectionKey.channel();
                            
                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                            channel.read(buffer);
                            
                            //eg: 把读取到的数据转换成字符串
                            System.out.println(new String(buffer.array()));
                        }
                    }
                    // 这里应该移除这个key
                    iterator.remove();
                }else {
    
                }
                
            } catch (IOException e) {
                e.printStackTrace();
            }
            
        }
        
        
        public static void main(String[] args) {
            ChatClient client = new ChatClient();
            
            new Thread() {
                @Override
                public void run() {
                    while (true) {
                        client.readInfo();
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                };
            }.start();
            
            
            Scanner scanner = new Scanner(System.in);
            
            while (scanner.hasNextLine()) {
                String msg = scanner.nextLine();
                client.sendMsg2Server(msg);
                
            }
            
            scanner.close();
        }
    }
    

    相关文章

      网友评论

          本文标题:NIO-03 多人聊天

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