2021-08-31 NIO群聊简易版服务端

3 篇文章 0 订阅
/**
 * @author Yang
 * @date 2021-08-31 14:16
 **/
public class testqunliaoServer {
    //定义selector选择器
    private Selector selector;
    //定义ServerSocketChannel通道
    private ServerSocketChannel serverSocketChannel;
    //服务器端口
    private final int PORT = 6666;

    //初始化
    public testqunliaoServer() {
        try {
            //初始化选择器
            selector = Selector.open();
            //初始化通道
            serverSocketChannel = ServerSocketChannel.open();
            //设置非阻塞
            serverSocketChannel.configureBlocking(false);
            //绑定监听端口
            serverSocketChannel.socket().bind(new InetSocketAddress(PORT));
            //注册到通道
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

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

    //监听方法
    public void listen(){
        try {
            while (true){
                int count = selector.select();
                if(count > 0){
                    //获取selectionKeys集合
                    Set<SelectionKey> selectionKeys = selector.selectedKeys();
                    //获取迭代器
                    Iterator<SelectionKey> iterator = selectionKeys.iterator();
                    while (iterator.hasNext()){
                        //获取SelectionKey
                        SelectionKey key = iterator.next();
                        //判断事件类型
                        if(key.isAcceptable()){//监听事件
                            //监听客户端,创建SocketChannel
                            SocketChannel sc = serverSocketChannel.accept();
                            //设置非阻塞
                            sc.configureBlocking(false);
                            //将SocketChannel注册到Selector,并监听read事件
                            sc.register(selector,
                                    SelectionKey.OP_READ);
                            System.out.println(sc.getRemoteAddress() + "上线...");
                        }
                        if(key.isReadable()){//读取事件
                            readInfo(key);
                        }
                        //处理结束后从集合中将当前selectionkey删除,防止重复操作
                        iterator.remove();
                    }

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

    }
    public void readInfo(SelectionKey key){
        //通过Selectionkey反向获取SocketChannel
        SocketChannel channel = (SocketChannel) key.channel();
        //创建buffer读取通道信息
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        try {
            int count = channel.read(buffer);
            if(count>0) {
                String msg = new String(buffer.array());
                System.out.println(channel.getRemoteAddress() + "消息:" + msg);
                //消息转发
                writeInfo(msg,channel);
            }
        }catch (IOException e){
            try {
                System.out.println(channel.getRemoteAddress() + "已离线...");
                key.cancel();
                channel.close();
            }catch (IOException e1){
                e1.printStackTrace();
            }
        }
    }
    public void writeInfo(String msg,SocketChannel sc){
        //获取selector中注册的通道集合
        Set<SelectionKey> keys = selector.keys();
        //遍历keys集合
        for(SelectionKey key:keys){
            //判断当前key的通道是否为socketchanel,且非消息发送通道
            Channel channel = key.channel();
            if(channel instanceof SocketChannel && channel != sc){
                //将消息写入到buffer
                ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());
                //将buffer中消息写入通道
                SocketChannel sc1 = (SocketChannel) channel;
                try {
                    sc1.write(buffer);
                    System.out.println("转发消息给:" + sc1.getRemoteAddress());
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值