Я пытаюсь связать Java DatagramChannel, чтобы прослушивать UDP-трафик на определенном порте и подинтерфейсе, но я не могу заставить его работать на моем Linux-хосте, где я создал несколько виртуальных сетей субинтерфейсы (в частности, тот, который я хочу прослушать, показан ниже). Код просто прекрасен, если я размещаю приложение Java на одном и том же сетевом компьютере под управлением Windows (используя другой IP-адрес, однако в этом случае для вызова вызова мне просто нужно было указать порт прослушивания, а также в окнах я не использую подинтерфейсы).Прослушивание датаграмм UDP с использованием Java DatagramChannel
Это соответствующий раздел выход IFCONFIG на моем Linux поле, показывая виртуальный сетевой адаптер (Субинтерфейс)
p2p1:37: flags=4163<UP,BnetROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.34.1 netmask 255.255.0.0 broadcast 192.168.255.255
ether 00:13:72:a5:9c:e2 txqueuelen 1000 (Ethernet)
device interrupt 16
Интерфейс был настройки следующим образом:
ifconfig p2p1:37 192.168.34.1 netmask 255.255.0.0
код, который я использую для инициализации неблокирующего DatagramChannel показано ниже: (Мне нужен DatagramChannel
, так как мне нужно использовать селектор для чтения из нескольких портов одновременно без блокировки). Я попробовал привязать только к адаптеру по умолчанию, используя номер порта, который хранится в entry.getValue()
через channel.socket().bind(new InetSocketAddress(entry.getValue())
, но он не получил никаких пакетов. Я где-то читал, что после создания DatagramChannel он по умолчанию создает сокет datagram, привязанный к «0.0.0.0» и однажды связанный с ним не может быть несвязан, но я не уверен ни в одном из них. Любое руководство будет высоко оценено.
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
updateMessage("Running...");
Map<String, DatagramChannel> dlmuChannelInfo = new HashMap<>();
Map<String, DatagramChannel> wsuChannelInfo = new HashMap<>();
try {
// array of bytes for receiving datagrams
ByteBuffer rxBuffer = ByteBuffer.allocateDirect(MAX_PACKET_SIZE);
for (Map.Entry<String, Integer> entry : mDLMUPortInfo.entrySet()) {
DatagramChannel channel = DatagramChannel.open();
// select only works with nonblocking channels
channel.configureBlocking(false);
// NetworkInterface iface = NetworkInterface.getByInetAddress(
// InetAddress.getByName("192.168.34.1"));
// List<NetworkInterface> list = Collections.list(
// NetworkInterface.getNetworkInterfaces());
// for (NetworkInterface next : list) {
// }
channel.socket().bind(new InetSocketAddress(
InetAddress.getByName("192.168.34.1"), entry.getValue()));
dlmuChannelInfo.put(entry.getKey(), channel);
}
// register for reads
try (
// instantiate a selector - note that this autocloses
Selector selector = Selector.open()) {
// register a selector for reads for both the DLMU & WSU
Map<SelectionKey, String> keyServiceInfo = new HashMap<>();
for (Map.Entry<String, DatagramChannel> entry : dlmuChannelInfo.entrySet()) {
SelectionKey key = entry.getValue().register(
selector, SelectionKey.OP_READ);
keyServiceInfo.put(key, entry.getKey());
}
@ EJB Я пробовал это, и, к сожалению, он не работает, у меня есть FTP-сервер, который также работает на этом виртуальном интерфейсе, и я могу войти в систему просто так, чтобы IP-адрес был жив и здоров. Единственная проблема, с которой я столкнулся, связана с тем, что это суб-интерфейс. Я попытался даже перечислить через subinterfaces и получил InetAddress из конкретного суб-интерфейса и использовал это безрезультатно. – johnco3