Java NIO - 数据报通道

  • 简述

    Java NIO 数据报用作通道,它可以通过连接较少的协议发送和接收 UDP 数据包。默认情况下,数据报通道处于阻塞状态,而它可以在非阻塞模式下使用。为了使其不阻塞,我们可以使用配置阻塞(假)方法。数据报通道可以通过调用其名为 open() 的静态方法之一来打开,该方法还可以将 IP 地址作为参数,以便用于多重转换。
    默认情况下,文件通道的数据报通道不连接,为了使它连接,我们必须显式调用其conting()方法。但是,数据报通道不需要连接即可使用发送和接收方法,而必须连接数据报通道才能使用读取和写入方法,因为这些方法不接受或返回套接字地址。
    我们可以通过调用其 isConnected() 方法来检查数据报通道的连接状态。连接后,数据报通道将保持连接状态,直到断开连接或关闭。数据报通道是线程安全的,同时支持多线程和并发。
  • 数据报通道的重要方法

    • bind(SocketAddress local) − 此方法用于将数据报通道的套接字绑定到作为此方法的参数提供的本地地址。
    • connect(SocketAddress remote) − 此方法用于将套接字连接到远程地址。
    • disconnect() − 此方法用于断开套接字与远程地址的连接。
    • getRemoteAddress() − 此方法返回通道套接字连接到的远程位置的地址。
    • isConnected() − 如前所述,此方法返回数据报通道的连接状态,即它是否连接。
    • open() 和 open(ProtocolFamily family) − 开放方法用于为单个地址打开数据报通道,而参数化开放方法为表示为协议系列的多个地址打开通道。
    • read(ByteBuffer dst) − 此方法用于通过数据报通道从给定缓冲区读取数据。
    • receive(ByteBuffer dst) − 此方法用于通过此通道接收数据报。
    • send(ByteBuffer src, SocketAddress target) − 此方法用于通过此通道发送数据报。
  • 下面的示例演示如何从 Java NIO 数据报通道发送数据。

    服务器: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();
       }
    }
    

    输出

    
    Server Started: localhost/127.0.0.1:8989
    

    客户端: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();
       }
    }
    

    输出

    运行客户端将在服务器上打印以下输出。
    
    Server Started: localhost/127.0.0.1:8989
    Client at /127.0.0.1:64857  sent: Hello World!