2016-09-27 3 views
0

Я пытаюсь связать 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()); 
         } 

ответ

0

Вы связываетесь с 192.168.34.1. Вы будете получать только датаграммы, отправленные на этот интерфейс. Если вы действительно не знаете, что делаете, вам следует привязать к 0.0.0.0, что делается , опуская параметр InetAddress или используя значение null.

Ваше замечание относительно DatagramSocket неправильное выполнение этой функции.

+0

@ EJB Я пробовал это, и, к сожалению, он не работает, у меня есть FTP-сервер, который также работает на этом виртуальном интерфейсе, и я могу войти в систему просто так, чтобы IP-адрес был жив и здоров. Единственная проблема, с которой я столкнулся, связана с тем, что это суб-интерфейс. Я попытался даже перечислить через subinterfaces и получил InetAddress из конкретного суб-интерфейса и использовал это безрезультатно. – johnco3

Смежные вопросы