UDP服务器使用一个未连接和多个连接的数据报通道,未按预期收到数据包

时间:2019-05-19 19:31:47

标签: java connect channel datagram

从下面的代码中可以看到,我正在尝试开发UDP服务器,据我的理解,阅读datagramchannel文档,连接的通道应该从指定的源接收数据包,但是始终是未连接的通道接收所有数据包。 我误会了什么吗?或执行实际上不支持的操作? 我知道你们中的某些人会说UDP是无连接协议等,但是尝试以这种方式进行操作的原因是为了使通道可以传递给其他类,以将响应发送回客户端,而其他类可能不知道从哪个地址和/或端口发送响应。

问候 约翰

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);
    }

0 个答案:

没有答案