2021-09-17

遍历Selector SelectionKey的Set集合时,如果都强转为SocketChannel时会抛类型转换异常

今天在学习Java NIO多人聊天室项目时,在将消息广播到其它客户端时,为了方便把Set集合中遍历到的项直接都强转为SocketChannel,服务器启动后客户端只发送了一条消息,客户端就停止了。代码如下:

// 消息广播到其它客户端
private void castOtherClient(Selector selector, SelectionKey selectionKey, String message) throws IOException, ClassCastException {
        SocketChannel channel = (SocketChannel)selectionKey.channel();
        Set<SelectionKey> channels = selector.keys();
        for (SelectionKey key : channels) {
            SocketChannel socketChannel = (SocketChannel) key.channel();
            if(socketChannel instanceof SocketChannel && socketChannel != channel) {
                socketChannel.write(Charset.forName("UTF-8").encode(message));
            }
        }
    }
}

发现问题后,修改如下:

// 消息广播到其它客户端
private void castOtherClient(Selector selector, SelectionKey selectionKey, String message) throws IOException, ClassCastException {
    SocketChannel channel = (SocketChannel)selectionKey.channel();
    Set<SelectionKey> channels = selector.keys();
    for (SelectionKey key : channels) {
        Channel curChannel = key.channel();
        if(curChannel instanceof SocketChannel && curChannel != channel)  {
            ((SocketChannel)curChannel).write(Charset.forName("UTF-8").encode(message));
        }
    }
}

由于在Selector中注册的通道有很多 FileChannel, SocketChannel, ServerSocketChannel, DatagramChannel 类型是不能强转为其中某一个,要先判断是哪个勒的实例 instanceof

上一篇:通过nio内存映射文件方式进行读/写操作


下一篇:多实例部署在一台服务器