gpt4 book ai didi

java - 如何在java nio中创建多个监听同一端口的udp客户端?

转载 作者:行者123 更新时间:2023-11-30 06:37:47 24 4
gpt4 key购买 nike

对于普通的io,我可以这样做:

s1=new DatagramSocket(1234)
s2=new DatagramSocket(1234)

bytes=xxxxxx
packet = DatagramPacket(bytes, bytes.size,InetSocketAddress("localhost",1234))
new DatagramSocket().send(packet)
// and then the s1 and s2 can receive the packet.

但在蔚来。这个怎么做?我尝试过这样的:

第一:

s1=DatagramChannel.open()
s1.bind(new Inetsocketaddress("localhost",1234)

s2=DatagramChannel.open()
s2.bind(new Inetsocketaddress("localhost",1234)// will throw an exception

第二个:

s1=DatagramChannel.open()
s1.setOption(StandardSocketOptions.SO_REUSEADDR, true);
s1.bind(new Inetsocketaddress("localhost",1234)

s2=DatagramChannel.open()
s2.setOption(StandardSocketOptions.SO_REUSEADDR, true);
s2.bind(new Inetsocketaddress("localhost",1234)

//these code will not throw exception. but s2 cannot receive any data.
// when i close s1, then s2 will receive data.

最佳答案

如果您确实需要所有客户端都处理消息,则需要多播/广播协议(protocol)。从这个意义上说,正如上一个问题( Does Java NIO support broadcast or multicast? )中所述,NIO2 支持多播和广播,但不使用 DatagramChannel 类。相反,您拥有 MultiCastChannel 接口(interface)(您可以在 http://javanio.info/filearea/nioserver/WhatsNewNIO2.pdf 中找到官方文档,并在 How do I implement a multicast client in NIO.2? 中找到示例)。关于您的代码,它应该如下所示:

   NetworkInterface netInterface = NetworkInterface.getByName("em1");
InetAddress group = InetAddress.getByName("localhost");

// Reader 1
System.out.println("Create Reader 1");
DatagramChannel s1 = DatagramChannel.open(StandardProtocolFamily.INET);
s1.setOption(StandardSocketOptions.SO_REUSEADDR, true);
s1.bind(new InetSocketAddress(PORT));
s1.setOption(StandardSocketOptions.IP_MULTICAST_IF, netInterface);

// Reader 2
System.out.println("Create Reader 2");
DatagramChannel s2 = DatagramChannel.open(StandardProtocolFamily.INET);
s2.setOption(StandardSocketOptions.SO_REUSEADDR, true);
s2.bind(new InetSocketAddress(PORT));
s2.setOption(StandardSocketOptions.IP_MULTICAST_IF, netInterface);

请注意,您的底层硬件堆栈必须支持多播/广播。否则,join 方法将抛出异常。

如果您不需要所有客户端都处理该消息,而是需要其中任何客户端处理该消息而不阻塞其他客户端,则可以设置非阻塞套接字选项。考虑到您提供的代码,我在下面添加了一个非阻塞的解决方案:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.charset.StandardCharsets;


public class Main {

private static final String HOST = "localhost";
private static final int PORT = 1234;

private static final String MESSAGE = "HelloWorld";
private static final int MESSAGE_SIZE = MESSAGE.length();


public static void main(String[] args) throws IOException {
// Reader 1
System.out.println("Create Reader 1");
DatagramChannel s1 = DatagramChannel.open();
s1.configureBlocking(false);
s1.setOption(StandardSocketOptions.SO_REUSEADDR, true);
s1.bind(new InetSocketAddress(HOST, PORT));

// Reader 2
System.out.println("Create Reader 2");
DatagramChannel s2 = DatagramChannel.open();
s2.configureBlocking(false);
s2.setOption(StandardSocketOptions.SO_REUSEADDR, true);
s2.bind(new InetSocketAddress(HOST, PORT));

// Writer
System.out.println("Create Writer");
DatagramChannel s3 = DatagramChannel.open();

// Send and receive messages
System.out.println("Send message");
send(s3);
System.out.println("Receive message on Reader 1");
receive(s1);
System.out.println("Receive message on Reader 2");
receive(s2);

// Close
System.out.println("Close");
s1.close();
s2.close();
s3.close();
}

private static void send(DatagramChannel channel) throws IOException {
ByteBuffer buf = ByteBuffer.allocate(MESSAGE_SIZE);
buf.clear();
buf.put(MESSAGE.getBytes());
buf.flip();

int bytesSent = channel.send(buf, new InetSocketAddress(HOST, PORT));
System.out.println("Sent: " + bytesSent);
}

private static void receive(DatagramChannel channel) throws IOException {
ByteBuffer buf = ByteBuffer.allocate(MESSAGE_SIZE);
buf.clear();

channel.receive(buf);

String str = new String(buf.array(), StandardCharsets.UTF_8);
System.out.println("Received: " + str);
}

}

输出是:

Create Reader 1
Create Reader 2
Create Writer
Send message
Sent: 10
Receive message on Reader 1
Received:
Receive message on Reader 2
Received: HelloWorld
Close

关于java - 如何在java nio中创建多个监听同一端口的udp客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44922595/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com