Java DatagramChannel — считывает все доступные дейтаграммы за один вызов «чтения»

#java #nio #multicast #datagram

#java #нио #многоадресная рассылка #дейтаграмма

Вопрос:

Я пытаюсь выяснить, как получить всю доступную дейтаграмму за один вызов чтения (который, надеюсь, будет переведен в один системный вызов), аналогично вызову rcvmmsg в C .

Прямо сейчас мой код выглядит следующим образом:

     private final Selector_;
    private final ByteBuffer buffer_ = ByteBuffer.allocate(2048);

    public UDPClient() {
        try {
            selector_ = Selector.open();
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }
    public void joinGroup(String group_ip, int group_port, String iface_name)  throws IOException {
        final NetworkInterface iface = NetworkInterface.getByName(iface_name);
        final DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET)
                .setOption(StandardSocketOptions.SO_REUSEADDR, true)
                .bind(new InetSocketAddress(group_port))
                .setOption(StandardSocketOptions.IP_MULTICAST_IF, iface);
        channel.configureBlocking(false);
        channel.join(InetAddress.getByName(group_ip), iface);
        channel.register(selector_, SelectionKey.OP_READ);
    }

    public void recvDatagrams() throws IOException {
        if (selector_.selectNow() > 0) {
            for (SelectionKey key: selector_.selectedKeys()) {
                final DatagramChannel channel = (DatagramChannel)key.channel();
                channel.receive(buffer_);
                buffer_.flip();
                // Handle buffer ...
                buffer_.clear();
            }
            selector_.selectedKeys().clear();
        }
    }
 

Мой желаемый код приема был бы примерно таким:

    ByteBuffer[] buffers_ = new ByteBuffer[64];
   // [...]
   channel.read(buffers_);
   // Handle datagrams
 

Это позволило бы мне получать до 64 дейтаграмм за один вызов, если они уже были поставлены в очередь в моем сетевом интерфейсе. Проблема, с которой я сталкиваюсь, заключается в том, что read() if для «подключенных» каналов. Мои каналы не подключены, я не знаю источника, я просто присоединяюсь к группе многоадресной рассылки и получаю от нее дейтаграммы.

Пожалуйста, обратите внимание, что я знаю, что могу выполнить while цикл при channel.receive() вызове для заполнения buffers_ массива самостоятельно, но это не является целью моего поста.

Ваше здоровье!

Комментарии:

1. DatagramChannel поддерживает рассеивание считываний при подключении. Он не поддерживает прием рассеяния.

2. Я ценю помощь в этом, Алан, к сожалению, это то, что я подозревал.