Java之UDP编程

DatagramSocket概述

上次在Java网络套接字Socket编程那篇博客里只写了Socket和ServerSocket,即TCP通信,这次来补充一下UDP通信。

和Socket类似的,Java中也存在一个DatagramSocket类,它就是面向UDP中的数据报包的概念传输,对应java.net包下面有一个类DatagramPacket就是用来描述数据报包。

因为UDP是无连接的,不分客户端和服务端,在单次通信中,只有发送端和接收端,因此也没有什么DatagramServerSocket

DatagramSocket使用

DatagramSocket():建立一个udp socket,它实际上是调用了DatagramSocket(new InetSocketAddress(0)),即指定端口号为0,0的含义是这个端口号是根据系统指定动态生成的。

其他构造函数就是和Socket类似的传一个端口号进去、传一个SocketAddress进去。

bind:绑定端口

connect:虽然udp是无连接的,但可以只与同一台机器通信,这种情况也称它为connect,connect之后所有的send和receive操作都与指定的主机通信。

send:发送一个DatagramPacket数据报包

receive:接收一个数据报包,这个方法是阻塞的。

close:释放socket

需要注意的是receive方法需要传入一个数据报包对象,这个数据报包对象由一个空的字节数组构造,而字节数组的长度值得考虑,如果过小可能会造成数据截断,所以发送方和接收方最好对数据包的大小制定约定规范。

示例:

@Test
public void testSend() throws IOException {
    DatagramSocket socket = new DatagramSocket();

    byte[] msg = "hello".getBytes();
    DatagramPacket packet = new DatagramPacket(msg, 0, msg.length, new InetSocketAddress("localhost", 12306));

    socket.send(packet);
    socket.close();
}

@Test
public void testReceive() throws IOException {
    DatagramSocket socket = new DatagramSocket(12306);
    byte[] buffer = new byte[1024];
    DatagramPacket packet = new DatagramPacket(buffer,0, buffer.length);
    socket.receive(packet);

    System.out.println(packet.getPort());
    System.out.println(new String(packet.getData(),0,packet.getLength()));
    socket.close();
}

DatagramChannel

需要了解的是,UDP本身就不存在什么阻塞,不需要连接,只在receive的时候会阻塞等待数据报。使用DatagramChannel可以设置非阻塞,则在从DatagramChannel中读数据报的时候如果没有数据报,就可以立即返回null。

相关API:public abstract SocketAddress receive(ByteBuffer dst) throws IOException;

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/java%e4%b9%8budp%e7%bc%96%e7%a8%8b/