DatagramChannel类的使用

本文深入探讨了DatagramChannel类的使用方法,包括如何创建、配置和使用该类进行UDP通信。文章详细介绍了DatagramChannel的特性,如并发读写支持、连接和断开连接的操作,并提供了具体的代码示例。

DatagramChannel类的使用

DatagramChannel类是针对面向DatagramSocket的可选择通道。DatagramChannel 不是DatagramSocket的完整抽象,必须通过调用socket() 方法获得的关联DatagramSocket对象来完成套接字选项的绑定和操作。不可能为任意的已有DatagramSocket创建通道,也不可能指定与DatagramChannel关联的DatagramSocket所使用的DatagramSocketImpl对象。

通过调用此类的open()方法创建DatagramChannel。新创建的DatagramChannel已打开,但尚未连接。使用send()和receive()方法,不需要将DatagramChannel进行连接,但是每次send和receive操作时都要执行安全检查,会造成系统开销,要避免这种情况也可以通过调用DatagramChannel的connect() 方法来建立DatagramChannel连接。为了使用read()和write()方法,必须建立DatagramChannel连接,因为这些方法不接受或返回套接字地址。

一旦建立连接,在断开DatagramChannel的连接或将其关闭之前,该DatagramChannel保持连接状态。可通过调用DatagramChannel的isConnected()方法来确定它是否已连接。
多个并发线程可安全地使用DatagramChannel。尽管在任意给定时刻最多只能有一个线程进行读取和写入操作,但DatagramChannel支持并发读写。

在这里插入图片描述

使用DatagramChannel类实现UDP通信
public static void main(String[] args) {
        try {
            DatagramChannel channel = DatagramChannel.open();
            channel.configureBlocking(false);
            //如果在两台物理计算机中进行实验,则要把localhost改成服务端的IP地址
            channel.bind(new InetSocketAddress("localhost", 8888));
            Selector selector = Selector.open();
            channel.register(selector, SelectionKey.OP_READ);
            boolean isRun = true;
            while (isRun) {
                selector.select();
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> it = selectionKeys.iterator();
                while (it.hasNext()) {
                    SelectionKey key = it.next();
                    if (key.isReadable()) {
                        channel = (DatagramChannel) key.channel();
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        channel.receive(byteBuffer);
                        System.out.println(new String(byteBuffer.array(), 0, byteBuffer.position()));
                    }
                    it.remove();
                }
                channel.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
public static void main(String[] args) {
        try {
            DatagramChannel channel = DatagramChannel.open();
            channel.configureBlocking(false);

            Selector selector = Selector.open();
            channel.register(selector, SelectionKey.OP_WRITE);
            int keyCount = selector.select();
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> it = selectionKeys.iterator();
            while (it.hasNext()) {
                SelectionKey key = it.next();
                if (key.isWritable()) {
                    ByteBuffer byteBuffer = ByteBuffer.wrap("我来自客户端!".getBytes());
                    //如果在两台物理计算机中进行实验,则要把localhost改成客户端的IP地址
                    channel.send(byteBuffer, new InetSocketAddress("localhost", 8888));
                    channel.close();
                }
            }
            System.out.println("client end!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
我来自客户端!
连接操作

public abstract DatagramChannel connect(SocketAddress remote)方法的作用是连接此通道的套接字。

服务端与上面一致,客户端如下:

public static void main(String[] args) {
        try {
            DatagramChannel channel = DatagramChannel.open();
            channel.configureBlocking(false);
            channel.connect(new InetSocketAddress("localhost", 8888));
            Selector selector = Selector.open();
            channel.register(selector, SelectionKey.OP_WRITE);
            int keyCount = selector.select();
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> it = selectionKeys.iterator();
            while (it.hasNext()) {
                SelectionKey key = it.next();
                if (key.isWritable()) {
                    ByteBuffer byteBuffer = ByteBuffer.wrap("我来自客户端!".getBytes());
                    channel.write(byteBuffer);
                    channel.close();
                }
            }
            System.out.println("client end!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
我来自客户端!
断开连接

public abstract DatagramChannel disconnect()方法的作用是断开此通道套接字的连接。
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值