NIO 实现群聊系统

服务器

java 复制代码
package chat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

/**
 * @author: zh
 * @create: 2023-09-13 10:52
 */
public class Server {

    private Selector selector;
    private ServerSocketChannel serverSocketChannel;
    private static final int PORT = 666;

    public Server() throws IOException {
        selector = Selector.open();
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.socket().bind(new InetSocketAddress(PORT));
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    }

    public void listen() throws IOException {
        while (true) {
            int count = selector.select();
            if (count > 0) {
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    if (key.isAcceptable()) {
                        SocketChannel socketChannel = serverSocketChannel.accept();
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector, SelectionKey.OP_READ);
                        System.out.println(socketChannel.getRemoteAddress() + " up");
                    } else if (key.isReadable()) {
                        read(key);
                    }
                    iterator.remove();
                }
            }
        }
    }

    private void read(SelectionKey key) throws IOException {
        SocketChannel socketChannel = null;
        try {
            socketChannel = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int count = socketChannel.read(buffer);
            if (count > 0) {
                String msg = new String(buffer.array());
                System.out.println(msg);
                send(msg, socketChannel);
            }
        } catch (Exception e) {
            System.out.println(socketChannel.getRemoteAddress() + " down");
            key.channel();
            socketChannel.close();
        }
    }

    private void send(String msg, SocketChannel self) throws IOException {
        System.out.println("send...");
        for (SelectionKey key : selector.keys()) {
            Channel channel = key.channel();
            if (channel instanceof SocketChannel && channel != self) {
                SocketChannel target = (SocketChannel) channel;
                ByteBuffer byteBuffer = ByteBuffer.wrap(msg.getBytes());
                target.write(byteBuffer);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        new Server().listen();
    }
}

客户端

java 复制代码
package chat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Scanner;

/**
 * @author: zh
 * @create: 2023-09-13 11:25
 */
public class Client {
    private static final int PORT = 666;
    private static final String HOST = "127.0.0.1";
    private SocketChannel socketChannel;
    private Selector selector;
    private String username;

    public Client() throws IOException {
        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("ready");
    }

    private void send(String info) throws IOException {
        info = username + " say " + info;
        socketChannel.write(ByteBuffer.wrap(info.getBytes()));
    }

    private void read() throws IOException {
        int count = selector.select();
        if (count > 0) {
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                if (key.isReadable()) {
                    SocketChannel channel = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    channel.read(buffer);
                    String msg = new String(buffer.array());
                    System.out.println(msg);
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        Client client = new Client();
        new Thread(() -> {
            while (true) {
                try {
                    client.read();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();

        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String msg = scanner.nextLine();
            client.send(msg);
        }
    }
}
相关推荐
我命由我1234521 小时前
Java NIO 编程 - NIO Echo Server、NIO Client(NIO 异步客户端、NIO Selector 异步客户端)
java·开发语言·网络·java-ee·intellij-idea·intellij idea·nio
懒惰蜗牛1 天前
Day63 | Java IO之NIO三件套--选择器(下)
java·nio·选择器·selector·半包粘包·tcp缓冲区
n***i955 天前
Java NIO文件操作
java·开发语言·nio
程序员-周李斌5 天前
Java NIO [非阻塞 + 多路复用解]
java·开发语言·开源软件·nio
onAcorner11 天前
Netty/Redis网络模型——IO多路复用原理(操作系统)
netty·nio
C2H5OH66615 天前
Netty详解-02
java·websocket·网络协议·tcp/ip·tomcat·netty·nio
Moshow郑锴19 天前
Spring Boot 多线程文件复制服务(支持大文件流式/NIO复制、失败重试、覆盖写入)
nio
java干货21 天前
BIO是“一人盯一桌”,NIO是“一人管全场”,AIO是“机器人送餐”
java·机器人·nio
Luo_xguan21 天前
一、Netty-高并发IO底层原理(5种主要的IO模型)
java·服务器·netty·nio
007php00722 天前
某游戏大厂的常用面试问题解析:Netty 与 NIO
java·数据库·游戏·面试·职场和发展·性能优化·nio