zoukankan      html  css  js  c++  java
  • 003-核心技术-IO模型-NIO-基于NIO群聊示例

    一、基于上节编写基础聊天

    GroupChatServer

    package com.github.bjlhx15.netty.demo.groupchat;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.*;
    import java.util.Iterator;
    
    public class GroupChatServer {
        private Selector selector;
        private ServerSocketChannel listenerChannel;
        private static final int PORT = 6667;
    
        public GroupChatServer() {
            try {
                selector = Selector.open();
                listenerChannel = ServerSocketChannel.open();
                listenerChannel.bind(new InetSocketAddress(PORT));
                listenerChannel.configureBlocking(false);
                listenerChannel.register(selector, SelectionKey.OP_ACCEPT);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public void listen() {
            try {
                while (true) {
                    int count = selector.select(2000);
                    if (count > 0) {
                        Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                        while (iterator.hasNext()) {
                            SelectionKey key = iterator.next();
                            if (key.isAcceptable()) {
                                SocketChannel socketChannel = listenerChannel.accept();
                                socketChannel.configureBlocking(false);
                                socketChannel.register(selector, SelectionKey.OP_READ);
                                System.out.println(socketChannel.getRemoteAddress() + " 上线");
                            }
                            if (key.isReadable()) {
                                readData(key);
                            }
                            //删除key防止重复处理
                            iterator.remove();
                        }
                    } else {
                        System.out.println("waiting……");
                    }
    
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
            }
        }
    
        private void readData(SelectionKey key) {
            SocketChannel channel = null;
            try {
                channel = (SocketChannel) key.channel();
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                int count = channel.read(buffer);
                if (count > 0) {
                    String msg = new String(buffer.array());
                    System.out.println("from 客户端 " + msg);
                    //向其他客户端转发消息
                    sendInfoToOtherClient(msg, channel);
                }
            } catch (IOException e) {
                try {
                    System.out.println(channel.getRemoteAddress() + " 离线了");
                    key.cancel();
                    channel.close();
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }
        }
    
        //    转发消息给其他客户(即通道)
        private void sendInfoToOtherClient(String msg, SocketChannel self) throws IOException {
            System.out.println("服务器转发消息");
            for (SelectionKey key : selector.keys()) {
                Channel targetChannel = key.channel();
                if (targetChannel instanceof SocketChannel && targetChannel != self) {
                    SocketChannel dest = (SocketChannel) targetChannel;
                    ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());
    
                    dest.write(buffer);
                }
            }
        }
    
        public static void main(String[] args) {
            GroupChatServer groupChatServer = new GroupChatServer();
            groupChatServer.listen();
        }
    }

    GroupChatClient

    package com.github.bjlhx15.netty.demo.groupchat;
    
    import sun.jvm.hotspot.oops.ByteField;
    
    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.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Iterator;
    import java.util.Scanner;
    
    public class GroupChatClient {
        private final String HOST = "127.0.0.1";
        private final int PORT = 6667;
        private Selector selector;
        private SocketChannel socketChannel;
        private String username;
    
        public GroupChatClient() throws IOException {
            selector = this.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 + " is ok^……");
        }
    
        public void sendInfo(String info) {
            info = username + " 说:" + info;
    
            try {
                socketChannel.write(ByteBuffer.wrap(info.getBytes()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public void readInfo() {
            try {
                int readChannels = selector.select();
                if (readChannels > 0) {
                    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                    while (iterator.hasNext()) {
                        SelectionKey key = iterator.next();
                        if (key.isReadable()) {
                            SocketChannel sc = (SocketChannel) key.channel();
                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                            sc.read(buffer);
                            String msg = new String(buffer.array());
                            System.out.println(msg.trim());
                        }
    //                    key.cancel();
                        iterator.remove();
                    }
                } else {
    //                System.out.println("没有可用通道");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) throws Exception {
            GroupChatClient chatClient = new GroupChatClient();
            new Thread() {
                @Override
                public void run() {
                    while (true) {
                        chatClient.readInfo();
                        try {
                            Thread.currentThread().sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
    
                }
            }.start();
            Scanner scanner = new Scanner(System.in);
            while (scanner.hasNextLine()) {
                String s = scanner.nextLine();
                chatClient.sendInfo(s);
            }
        }
    }
    转载请注明出处,感谢。
    作者:李宏旭
    阅罢此文,如果您觉得本文不错并有所收获,请【打赏】或【推荐】,也可【评论】留下您的问题或建议与我交流。
    你的支持是我不断创作和分享的不竭动力!
  • 相关阅读:
    如何提高PHP执行效率
    PHP MySQL 预处理语句
    CDN拾遗
    Rendering React components to the document body
    模拟select,隐藏下拉列表的几种实现
    前端数据范式化
    其实我们可以少写点if else和switch
    [译]the cost of javascript in 2018(1)
    provisional headers are shown 知多少
    f5到底刷新了点什么,你知道吗
  • 原文地址:https://www.cnblogs.com/bjlhx/p/15072954.html
Copyright © 2011-2022 走看看