Сервер UDP использует один неподключенный и несколько подключенных каналов дейтаграммы, пакеты не получены, как ожидалось - PullRequest
0 голосов
/ 19 мая 2019

Как вы можете видеть из приведенного ниже кода, я пытаюсь разработать UDP-сервер, и, насколько я понимаю, читая документы datagramchannel, я вижу, что подключенный канал должен получать пакеты из указанного источника, однако это всегда неподключенный канал, получает все пакеты. Я что-то не так понял? или делать что-то, что на самом деле не поддерживается? Я знаю, что некоторые из вас скажут, что UDP является протоколом без установления соединения и т. Д., Но причина попытки сделать это таким образом заключается в том, что канал может быть передан другим классам для отправки ответов клиенту, а эти другие классы могут не знать с какого адреса и / или порта отправлять ответ.

С уважением John

protected void init() throws IOException {
        connections = new HashMap<>();
        datagramChannel = DatagramChannel.open();
        datagramChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
        datagramChannel.configureBlocking(false);
        datagramChannel.bind(getSocketAddress());
        selector = Selector.open();
        baseKey = datagramChannel.register(selector, SelectionKey.OP_READ);
    }

    @Override
    public void run() {
        while (!Thread.interrupted()) {
            try {
                if (selector.select(1000) != 0) {
                    // We have a ready channel.
                    Set<SelectionKey> selectedKeys = selector.selectedKeys();
                    selectedKeys.forEach((key) -> {
                        if (key.isValid() && key != baseKey) {
                            System.out.println("Client channel has data " + key);
                        } else if (key.isValid()) {
                            if (key.isReadable()) {
                                try {
                                    createClientConnection((DatagramChannel) key.channel());
                                    System.out.println(selector.keys());
                                } catch (IOException ex) {
                                    Logger.getLogger(AbstractUdpServer.class.getName()).log(Level.SEVERE, null, ex);
                                }
                            }
                        }
                        selectedKeys.remove(key);
                    });
                } else {
                    System.out.println("No channels ready");
                }
            } catch (IOException ex) {
                Logger.getLogger(AbstractUdpServer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private void createClientConnection(DatagramChannel channel) throws IOException {
        ByteBuffer dst = ByteBuffer.allocateDirect(16384);
        SocketAddress remoteAddress = channel.receive(dst);
        System.out.println("New client " + remoteAddress);
        // now create a connection.
        DatagramChannel client = DatagramChannel.open();
        client.setOption(StandardSocketOptions.SO_REUSEADDR, true);
        client.configureBlocking(false);
        client.bind(getSocketAddress());
        client.connect(remoteAddress);
        client.register(selector, SelectionKey.OP_READ);
    }
...