Java Nio 简明教程

Java NIO - Datagram Channel

Java NIO Datagram 用作在无连接协议上发送和接收 UDP 数据包的通道。默认情况下,数据报通道在阻塞,虽然它可以在非阻塞模式下使用。为了使它非阻塞,我们可以使用 configureBlocking(false) 方法。数据报通道可以通过调用其名为 open() 的静态方法之一来打开,该方法还可以使用 IP 地址作为参数,以便可以用于多播。

数据报通道类似于 FileChannel,默认情况下不进行连接,因此为了实现连接,我们必须显式调用其 connect() 方法。然而,数据报通道不需要连接才能使用 send 和 receive 方法,而它必须连接才能使用 read 和 write 方法,因为那些方法不接受或不返回套接字地址。

我们可以通过调用其 isConnected() 方法来检查数据报通道的连接状态。一旦连接,数据报通道将一直保持连接状态,直到它断开或关闭。数据报通道是线程安全的,并且同时支持多线程和并发。

Important methods of datagram channel

  1. bind(SocketAddress local) − 此方法用于将数据报通道的套接字绑定到作为此方法的参数提供的本地地址。

  2. connect(SocketAddress remote) − 此方法用于将套接字连接到远程地址。

  3. disconnect() − 此方法用于断开与远程地址的套接字连接。

  4. getRemoteAddress() - 该方法返回通道 Socket 连接到的远程位置的地址。

  5. isConnected() − 如前所述,此方法返回数据报通道连接状态,即是否已连接。

  6. open() and open(ProtocolFamily family) − open 方法用于为单个地址打开数据报通道,而参数化 open 方法为用作协议族表示的多个地址打开通道。

  7. read(ByteBuffer dst) − 此方法用于通过数据报通道从给定的缓冲区读取数据。

  8. receive(ByteBuffer dst) − 此方法用于通过此通道接收数据报。

  9. send(ByteBuffer src, SocketAddress target) − 此方法用于通过此通道发送数据报。

Example

以下示例显示如何通过 Java NIO DataGramChannel 发送数据。

Server: DatagramChannelServer.java

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;

public class DatagramChannelServer {
   public static void main(String[] args) throws IOException {
      DatagramChannel server = DatagramChannel.open();
      InetSocketAddress iAdd = new InetSocketAddress("localhost", 8989);
      server.bind(iAdd);
      System.out.println("Server Started: " + iAdd);
      ByteBuffer buffer = ByteBuffer.allocate(1024);
      //receive buffer from client.
      SocketAddress remoteAdd = server.receive(buffer);
      //change mode of buffer
      buffer.flip();
      int limits = buffer.limit();
      byte bytes[] = new byte[limits];
      buffer.get(bytes, 0, limits);
      String msg = new String(bytes);
      System.out.println("Client at " + remoteAdd + "  sent: " + msg);
      server.send(buffer,remoteAdd);
      server.close();
   }
}

Output

Server Started: localhost/127.0.0.1:8989

Client: DatagramChannelClient.java

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;

public class DatagramChannelClient {
   public static void main(String[] args) throws IOException {
      DatagramChannel client = null;
      client = DatagramChannel.open();

      client.bind(null);

      String msg = "Hello World!";
      ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());
      InetSocketAddress serverAddress = new InetSocketAddress("localhost",
        8989);

      client.send(buffer, serverAddress);
      buffer.clear();
      client.receive(buffer);
      buffer.flip();

      client.close();
   }
}

Output

运行客户端将在服务器上打印以下输出。

Server Started: localhost/127.0.0.1:8989
Client at /127.0.0.1:64857  sent: Hello World!