Java NIO-DatagramChannel

Java NIO 数据报管道,原文地址:http://tutorials.jenkov.com/java-nio/datagram-channel.html

一个 Java NIO 数据报管道是一种可以收发 UDP 数据报的管道。因为 UDP 协议是一个无连接协议,因此你不能像其他管道那样读写管道。相应地,你可以从数据包中收发数据。

打开一个数据报通道

下面是打开一个数据报通道的语法:

1
2
DatagramChannel channel = DatagramChannel.open();
channel.socket().bind(new InetSocketAddress(9999));

这个例子打开了一个在 9999 端口监听的 UDP 数据报通道。

接收数据

你可以通过调用 DatagramChannel 的 receive() 方法来接收数据,就像下面这样:

1
2
3
4
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
channel.receive(buf);

receive() 方法将会把数据报中的数据复制到字节缓冲区中。如果数据报中包含的数据超过了字节缓冲区的容量,剩下的数据默认会被丢弃。

发送数据

你可以通过 DatagramChannel 的 send() 方法来发送数据,就像下面这样:

1
2
3
4
5
6
7
8
String newData = "New String to write to file..." + System.currentTimeMillis();
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
int byteSent = channel.send(buf, new InetSocketAddress("jenkov.com", 80));

这个例子发送了一个字符串到 “jenkov.com” 服务器的 80 端口。由于该服务器上没有任何服务在 80 端口监听,所以实际上什么也不会发生。你不会知道你发送的数据报对方是否收到,因为 UDP 协议就是一种不可靠的传输协议。

连接到指定地址

你也可以把数据报管道“连接”到一个指定的远程地址。因为 UDP 协议是一个无连接协议,因此这里所说的“连接”并不会创建一个像 TCP 管道那样真实的连接。这里所谓的“连接”意味着锁定了你的数据报通道,使你只能和一个远程机器通过 UDP 协议通信,收发数据。
连接语法:

1
channel.connect(new InetSocketAddress("jenkov.com", 80));

连接之后你可以照常使用 read() 和 write() 方法收发数据,就像是在使用一个 TCP 管道一样。但仍不能保证发送的数据一定会被对方收到:

1
2
3
int bytesRead = channel.read(buf);
int bytesWritten = channel.write(buf);