NIO实现群聊系统

  • server服务器端
public class ServerDemo1 {
    public static final int PORT=10085;
    public Selector selector;
    public ServerSocketChannel serverSocketChannel;
    public ByteBuffer sendBuffer;
    public ByteBuffer recBuffer;

    public ServerDemo1() {
        sendBuffer=ByteBuffer.allocate(1024);
        recBuffer=ByteBuffer.allocate(1024);

        try {
            this.selector=Selector.open();

            this.serverSocketChannel=ServerSocketChannel.open();
            this.serverSocketChannel.bind(new InetSocketAddress(PORT));
            this.serverSocketChannel.configureBlocking(false);
            this.serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            
            System.out.println("server success init");


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

    }

    /**
     * 监听方法
     * @throws IOException
     */
    private void listen() throws IOException {
        while (true){
            int select = selector.select();
            if (select > 0){
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                if (selectionKeys.isEmpty()){
                    continue;
                }
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()){
                    SelectionKey nextkey = iterator.next();
                    handle(nextkey);
                    iterator.remove();
                }

            }
        }
    }

    /**
     * 判断事件类型
     * @param nextkey
     */
    private void handle(SelectionKey nextkey) {
        SocketChannel client=null;
        try{
            if (nextkey.isValid() && nextkey.isAcceptable()){
                client = serverSocketChannel.accept();
                client.configureBlocking(false);
                client.register(selector,SelectionKey.OP_READ);
            } else if (nextkey.isReadable()){
                client  = (SocketChannel) nextkey.channel();
                recBuffer.clear();
                int read = client.read(recBuffer);
                if (read > 0){
                    String message = new String(recBuffer.array(), 0, read);
                    System.out.println("server收到客户端信息现在转发"+client.getRemoteAddress()+message);
                    //client.register(selector,SelectionKey.OP_WRITE);
                    sendToOtherclient(message,client );
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 服务器转发消息给其他客户端
     * @param message
     * @param selfclient
     */
    private void sendToOtherclient(String message, SocketChannel selfclient) throws IOException {
        Channel targetclient;
        for (SelectionKey selectkey:selector.keys()) {
            targetclient= selectkey.channel();
            if (targetclient instanceof SocketChannel && targetclient != selfclient && targetclient != serverSocketChannel){
                SocketChannel desc= (SocketChannel) targetclient;
                sendBuffer.clear();
                sendBuffer.put(message.getBytes());
                sendBuffer.flip();
                desc.write(sendBuffer);
            }
        }
    }


    public static void main(String[] args) throws IOException {

        ServerDemo1 serverDemo1 = new ServerDemo1();
        serverDemo1.listen();

    }
}

  • client客户端
public class ClientDemo1 {
    private static final int PORT=10085;
    private static final String  IP="127.0.0.1";
    private SocketChannel socketChannel;
    private ByteBuffer sendBuffer;
    private ByteBuffer recBuffer;

    public ClientDemo1() {
        this.recBuffer=ByteBuffer.allocate(1024);
        this.sendBuffer=ByteBuffer.allocate(1024);

        try {
            socketChannel=SocketChannel.open();
            socketChannel.configureBlocking(false);
            socketChannel.connect(new InetSocketAddress(IP,PORT));
            System.out.println(socketChannel.getRemoteAddress()+"客户端初始化完毕");
            connectServer();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 连接服务器
     * @throws IOException
     */
    private void connectServer() throws IOException {
        System.out.println("客户端开始连接");
        if (socketChannel.isConnectionPending()){
            socketChannel.finishConnect();
            sendMessage(socketChannel.getRemoteAddress()+"用户上线!");
        }
    }

    /**
     * 发送消息给服务器
     * @param message
     */
    public void sendMessage(String message) throws IOException {
        sendBuffer.clear();
        sendBuffer.put(message.getBytes());
        sendBuffer.flip();
        socketChannel.write(sendBuffer);
    }

    public void recMessage() throws IOException {
        recBuffer.clear();
        int read = socketChannel.read(recBuffer);
        if (read > 0){
            String message=new String(recBuffer.array(),0,read);
            System.out.println("来自其他客户端的消息--"+message);
        }

    }


    public static void main(String[] args) throws IOException {
        ClientDemo1 clientDemo1 = new ClientDemo1();
        //创建一个线程来不断收来自服务器的消息
        new Thread(()->{
            while (true){
                try {
                    clientDemo1.recMessage();
                    Thread.sleep(2000);
                } catch (IOException | InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();


        //不断通过输入来给服务器发消息
        Scanner scanner=new Scanner(System.in);
        System.out.println("输入你想要发送的信息");
        while (scanner.hasNext()){
            System.out.println("输入你想要发送的信息");
            String message=scanner.nextLine();
            try {
                clientDemo1.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值