NIO-Socket实现简易聊天室

NIO实现通信聊天:

服务端步骤:

1.创建NI0通道,并且绑定端口

2.开启非阻塞模式

3.创建Selector选择器,并将通道注册到选择器上边,设置关系事件---》新链接

4.循环监听通道的事件

5.监听到新连接事件

5.1:建立和客户端连接的通道

5.2:通道设置为非阻塞

5.3:通道设置完成,将关系事件设置为读取

6.监听到读取事件

6.1:获取客户端通道

6.2:将通道的数据写入到缓冲区(buffer)当中

6.3:打印数据

服务器端:

public class Server {
    public static void main(String[] args) throws IOException {
        // 获取一个ServerSocket通道
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        // serverChannel通道一直监听4700端口
        serverChannel.socket().bind(new InetSocketAddress(4700));
        // 设置serverChannel为非阻塞
        serverChannel.configureBlocking(false);
        //创建Selector选择器用来监听通道
        Selector selector = Selector.open();
        // 把ServerSocketChannel注册到selector中,并且selector对客户端的连接操作感兴趣
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("服务启动成功!");

        while (true) {
            /*
             * 如果事件没有到达 selector.select() 会一直阻塞等待
             */
            selector.select();
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                if (key.isAcceptable()) // 如果是OP_ACCEPT事件,则进行连接获取和事件注册
                {
                    ServerSocketChannel server = (ServerSocketChannel) key.channel(); //连接获取
                    SocketChannel socketChannel = server.accept(); // 获取通道
                    socketChannel.configureBlocking(false); // 设置为非阻塞
                    socketChannel.register(selector, SelectionKey.OP_READ); //这里只注册了读事件,如果需要给客户端写数据,则需要注册写事件
                    System.out.println("客户端连接成功!");
                } else if (key.isReadable()) //如果是OP_READ事件,则进行读取和打印
                {
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    ByteBuffer byteBuffer = ByteBuffer.allocate(128);//创建Buffer
                    int len = socketChannel.read(byteBuffer);
                    if (len > 0) //如果有数据,则打印数据
                    {
                        System.out.println("接受到客户端数据" + new String(byteBuffer.array()));
                    }
                }
                // 从事件集合中删除本次处理的key,防止下次select重复处理
                iterator.remove();

            }
        }
    }
}

客户端:

public class Client {
    public static void main(String[] args) throws IOException {
        //打开channel通道
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.configureBlocking(false); //设置为非阻塞
        InetSocketAddress address = new InetSocketAddress("101.43.152.120",4700);
        while (!socketChannel.connect(address)){
            while (!socketChannel.finishConnect()){
                System.out.println("连接中,客户端可以进行其他工作");
            }
//            Scanner scanner = new Scanner(System.in);
//            String str  = scanner.next();
            Scanner scanner=new Scanner(System.in);
            do {
                String str=scanner.next();
                ByteBuffer aa = ByteBuffer.wrap(str.getBytes());  // 将数据转换成字节信息写入到Buffer当中
                socketChannel.write(aa); //将Buffer当中的数据写入channel
            } while (!scanner.equals("bye"));
            scanner.close();

            System.in.read();
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值