Netty学习--NIO简单聊天室实现

ChatServer

public class ChatServer {

    private Selector selector;

    private ServerSocketChannel serverSocketChannel;

    private static final int PORT = 7777;

    /**
    * 初始化操作
    */
    public ChatServer() {
        try {
            serverSocketChannel = ServerSocketChannel.open();
            selector = Selector.open();
            InetSocketAddress inetSocketAddress = new InetSocketAddress(PORT);
            serverSocketChannel.socket().bind(inetSocketAddress);  //绑定通讯端口
            serverSocketChannel.configureBlocking(false); //设置为非阻塞
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);  //注册accept事件
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void listen() {
        try {
            while(true) {//轮询监听事件
                int count = selector.select();
                if(count > 0) {  //监听到了事件发生
                    //1.输出上线客户端,并通知其他在线客户端
                    Set<SelectionKey> selectionKeySet = selector.selectedKeys();
                    Iterator<SelectionKey> iterator = selectionKeySet.iterator();
                    while(iterator.hasNext()) {
                        SelectionKey key = iterator.next();
                        if(key.isAcceptable()) {  //连接事件处理
                            SocketChannel socketChannel = serverSocketChannel.accept();
                            socketChannel.configureBlocking(false);
                            String message = "client:" + socketChannel.getRemoteAddress() + "上线了";
                            System.out.println(message);
                            socketChannel.register(selector, SelectionKey.OP_READ);  //注册read事件
                            notifyOthers(message, socketChannel); //发送上线通知给其他客户端
                        } else if (key.isReadable()) { //读取数据处理
                            try {
                                ByteBuffer buffer = ByteBuffer.allocate(1024);
                                SocketChannel socketChannel = (SocketChannel)key.channel();
                                socketChannel.read(buffer);
                                String message = new String(buffer.array());
                                System.out.println("client " + socketChannel.getRemoteAddress().toString().substring(1) +
                                        " : " + message);
                                notifyOthers(message, socketChannel); //通知其他客户端
                            } catch (IOException e) {
                                SocketChannel socketChannel = (SocketChannel)key.channel();
                                System.out.println("client:" + socketChannel.getRemoteAddress().toString().substring(1) +
                                        "离线了");
                                key.cancel();
                                socketChannel.close();
                            }
                        }
                        iterator.remove();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void notifyOthers(String message, SocketChannel socketChannel) {
        //遍历key集合,排除当前的socketChannel
        for (SelectionKey key : selector.keys()) {
            Channel channel = key.channel();
            //注册到key中的channel有两种可能:ServerSocketChannel和SocketChannel
            //所以这里需要先判断类型,再进行比较
            if(channel instanceof SocketChannel && channel != socketChannel) {
                ByteBuffer byteBuffer = ByteBuffer.wrap(message.getBytes());
                SocketChannel dest = (SocketChannel)channel;
                //将buffer 的数据写入通道
                try {
                    dest.write(byteBuffer);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {

        new ChatServer().listen();

    }
}

ChatClient

public class ChatClient {

    private Selector selector;

    private SocketChannel socketChannel;

    public void connectServer() {
        try {
            selector = Selector.open();
            socketChannel = SocketChannel.open();
            InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 7777);
            socketChannel.connect(inetSocketAddress);
            if(!socketChannel.isConnected()) {
                System.out.println("客户端" + socketChannel.getLocalAddress() + "正在连接中,请耐心等待");
                while (!socketChannel.finishConnect()) {
                    continue;
                }
            }
            socketChannel.configureBlocking(false);
            socketChannel.register(selector, SelectionKey.OP_READ);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(String message) {
        ByteBuffer byteBuffer = ByteBuffer.wrap(message.getBytes());
        try {
            socketChannel.write(byteBuffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void readData() {
        int count = 0;
        try {
            count = selector.select();
            if(count > 0) {
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    if(key.isReadable()) {
                        SocketChannel socketChannel = (SocketChannel)key.channel();
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        socketChannel.read(byteBuffer);
                        System.out.println(new String(byteBuffer.array()));
                    }
                    iterator.remove();
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ChatClient chatClient = new ChatClient();
        ExecutorService executor = Executors.newFixedThreadPool(10);
        executor.execute(new Runnable() {
            public void run() {
                chatClient.connectServer();
                while (true) {
                    chatClient.readData();
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()) {
            String s = scanner.nextLine();
            chatClient.sendMessage(s);
        }

    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值