Server.java 4.3 KB
package two;

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.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Server {
    private static final int BUFFER_SIZE = 1024;
    private static final int PORT = 8877;

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

    public static void main(String[] args) {
        Server server = new Server();
        server.startServer();
    }

    public void startServer() {
        try {
            // 创建Selector对象和ServerSocketChannel对象,并将ServerSocketChannel注册到Selector上,监听连接事件。
            selector = Selector.open();
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);
            serverSocketChannel.socket().bind(new InetSocketAddress(PORT));
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("Server started on port " + PORT);

            // 进入主循环
            while (true) {
                // 调用Selector的select()方法等待事件发生
                int readyChannels = selector.select();
                if (readyChannels == 0) {
                    continue;
                }

                // 如果有事件发生,使用迭代器遍历SelectionKey集合,处理每个事件。
                Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
                while (keyIterator.hasNext()) {
                    SelectionKey key = keyIterator.next();

                    // 如果是连接事件,使用ServerSocketChannel的accept()方法接受客户端连接,
                    // 并将客户端的SocketChannel注册到Selector上,监听读事件。
                    if (key.isAcceptable()) {
                        SocketChannel clientChannel = serverSocketChannel.accept();
                        clientChannel.configureBlocking(false);
                        clientChannel.register(selector, SelectionKey.OP_READ);
                        System.out.println("New client connected: " + clientChannel.getRemoteAddress());
                        clientMap.put(clientChannel, "");
                    }

                    // 如果是读事件,使用SocketChannel的read()方法读取客户端发送的消息,并将其转发给其他客户端。
                    if (key.isReadable()) {
                        SocketChannel clientChannel = (SocketChannel) key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
                        int bytesRead = clientChannel.read(buffer);
                        if (bytesRead > 0) {
                            String message = new String(buffer.array()).trim();
                            if (clientMap.get(clientChannel).equals("")) {
                                clientMap.put(clientChannel, message);
                                System.out.println("New user registered: " + message);
                                broadcast(message + "上线啦 ", clientChannel);
                            } else {
                                System.out.println("Message received from " + clientMap.get(clientChannel) + ": " + message);
                                broadcast(clientMap.get(clientChannel) + ": " + message, clientChannel);
                            }
                        }
                    }

                    // 处理完事件后,使用迭代器的remove()方法将SelectionKey从集合中删除。
                    keyIterator.remove();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void broadcast(String message, SocketChannel senderChannel) throws IOException {

        for (SocketChannel clientChannel : clientMap.keySet()) {
            if (clientChannel != senderChannel) {
                //多个对象发送,每次都得载一个新的对象,不然就只能发送一次
                ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());
                clientChannel.write(buffer);
            }
        }
    }
}