拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Java NIO DatagramChannel

Java NIO DatagramChannel

白鹭 - 2021-11-24 398 0 0

1.概述

在本教程中,我们将探索DatagramChannel类,该类允许我们发送和接收UDP数据包。

2. DatagramChannel

在Internet支持的各种协议中,TCP和UDP是最常见的。

TCP是面向连接的协议,而UDP是高性能且可靠性较低的面向数据报的协议UDP由于其不可靠的特性而经常用于发送广播或多播数据传输。

Java的NIO模块的DatagramChannel类为面向数据报的套接字提供了一个可选通道。换句话说,它允许创建一个数据报通道来发送和接收数据报(UDP数据包)。

让我们使用DatagramChannel类创建一个客户端,该客户端通过本地IP地址发送数据报,并创建一个接收数据报的服务器。

3.打开并绑定

首先,让我们openChannel DatagramChannelBuilder类,该方法提供一个打开但未连接的数据报通道:

public class DatagramChannelBuilder {

 public static DatagramChannel openChannel() throws IOException {

 DatagramChannel datagramChannel = DatagramChannel.open();

 return datagramChannel;

 }

 }

然后,我们需要将一个打开的通道绑定到本地地址,以侦听入站UDP数据包。

因此,我们将添加bindChannel方法, DatagramChannel绑定到提供的本地地址:

public static DatagramChannel bindChannel(SocketAddress local) throws IOException {

 return openChannel().bind(local);

 }

现在,我们可以使用DatagramChannelBuilder类来创建客户端/服务器,该客户端/服务器在已配置的套接字地址上发送/接收UDP数据包。

4.客户端

首先,让我们创建DatagramClient与类startClient使用已经讨论过的方法bindChannel的方法DatagramChannelBuilder类:

public class DatagramClient {

 public static DatagramChannel startClient() throws IOException {

 DatagramChannel client = DatagramChannelBuilder.bindChannel(null);

 return client;

 }

 }

由于客户端不需要侦听入站UDP数据包,因此在绑定通道时我们为地址null

然后,我们添加sendMessage方法以在服务器地址上发送数据报:

public static void sendMessage(DatagramChannel client, String msg, SocketAddress serverAddress) throws IOException {

 ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());

 client.send(buffer, serverAddress);

 }

就是这样!现在,我们准备使用客户端发送消息:

DatagramChannel client = startClient();

 String msg = "Hello, this is a Baeldung's DatagramChannel based UDP client!";

 InetSocketAddress serverAddress = new InetSocketAddress("localhost", 7001);



 sendMessage(client, msg, serverAddress);

注意:将消息发送到localhost:7001地址后,必须使用相同的地址启动服务器。

5.服务器

同样,让我们startServer DatagramServer类, localhost:7001地址上启动服务器:

public class DatagramServer {

 public static DatagramChannel startServer() throws IOException {

 InetSocketAddress address = new InetSocketAddress("localhost", 7001);

 DatagramChannel server = DatagramChannelBuilder.bindChannel(address);

 System.out.println("Server started at #" + address);

 return server;

 }

 }

然后,让我们添加receiveMessage方法,该方法从客户端接收数据报,提取消息并打印:

public static void receiveMessage(DatagramChannel server) throws IOException {

 ByteBuffer buffer = ByteBuffer.allocate(1024);

 SocketAddress remoteAdd = server.receive(buffer);

 String message = extractMessage(buffer);

 System.out.println("Client at #" + remoteAdd + " sent: " + message);

 }

另外,要从接收的缓冲区中提取客户端的消息,我们将需要添加extractMessage方法:

private static String extractMessage(ByteBuffer buffer) {

 buffer.flip();

 byte[] bytes = new byte[buffer.remaining()];

 buffer.get(bytes);

 String msg = new String(bytes);



 return msg;

 }

在这里,我们ByteBuffer flip方法,以将其从I / O读取转换为写入I / O。另外, flip方法将限制设置为当前位置,并将位置设置为零,以便我们从头开始阅读。

现在,我们可以启动服务器并接收来自客户端的消息:

DatagramChannel server = startServer();

 receiveMessage(server);

因此,服务器收到我们的消息时,打印输出将是:

Server started at #localhost/127.0.0.1:7001

 Client at #/127.0.0.1:52580 sent: Hello, this is a Baeldung's DatagramChannel based UDP client!

6. DatagramChannelUnitTest

现在我们已经准备好客户端和服务器,我们可以编写一个单元测试来验证端到端数据报(UDP数据包)的传递:

@Test

 public void whenClientSendsAndServerReceivesUDPPacket_thenCorrect() throws IOException {

 DatagramChannel server = DatagramServer.startServer();

 DatagramChannel client = DatagramClient.startClient();

 String msg1 = "Hello, this is a Baeldung's DatagramChannel based UDP client!";

 String msg2 = "Hi again!, Are you there!";

 InetSocketAddress serverAddress = new InetSocketAddress("localhost", 7001);



 DatagramClient.sendMessage(client, msg1, serverAddress);

 DatagramClient.sendMessage(client, msg2, serverAddress);



 assertEquals("Hello, this is a Baeldung's DatagramChannel based UDP client!", DatagramServer.receiveMessage(server));

 assertEquals("Hi again!, Are you there!", DatagramServer.receiveMessage(server));

 }

首先,我们启动了绑定数据报通道的服务器,以侦听localhost:7001上的入站消息。然后,我们启动了客户端并发送了两条消息。

最后,我们在服务器上收到入站消息,并将它们与我们通过客户端发送的消息进行比较。

7.附加方法

到目前为止,我们已经使用**DatagramChannel类提供的openbindsendreceive之类的方法**。现在,让我们快速浏览一下其他方便的方法。

7.1 configureBlocking

默认情况下,数据报通道处于阻塞状态。 false值时,我们可以使用configureBlocking方法使通道变为非阻塞状态:

client.configureBlocking(false);

7.2 isConnected

isConnected方法返回数据报通道的状态-即它是已连接还是已断开连接。

7.3 socket

socket方法返回与数据报通道关联DatagramSocket

7.4。close

另外,我们可以通过调用DatagramChannelclose方法来关闭通道。

8.结论

在本快速教程中,我们探讨了Java NIO的DatagramChannel类,该类允许创建一个数据报通道来发送/接收UDP数据包。

首先,我们研究了一些方法,例如openbind ,它们同时允许数据报通道侦听入站UDP数据包。

然后,我们创建了一个客户端和一个服务器, DatagramChannel类探索端到端UDP数据包的传递

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *