数据报通道套接字不写入Java

数据报通道套接字不写入Java,java,android,sockets,channel,datagram,Java,Android,Sockets,Channel,Datagram,简单地说,我能够从连接的套接字接收数据,直到它启动后大约10秒。解决这一问题的方法是,向“客户端”(一个ARDrone)发送数据,以保持数据流继续,否则它将停止向手机发送数据。然而,出于某种原因,我当前的代码只在第一次连接时将数据写入客户机(ARDrone),而不会在第二次连接后写入。我需要它在套接字通信后继续向ARDrone发送数据 我试着在通道.register()调用中移动,但我所做的一切似乎都没有按照我的需要将数据发送到ARDrone 创建连接: channel = DatagramCh

简单地说,我能够从连接的套接字接收数据,直到它启动后大约10秒。解决这一问题的方法是,向“客户端”(一个ARDrone)发送数据,以保持数据流继续,否则它将停止向手机发送数据。然而,出于某种原因,我当前的代码只在第一次连接时将数据写入客户机(ARDrone),而不会在第二次连接后写入。我需要它在套接字通信后继续向ARDrone发送数据

我试着在
通道.register()
调用中移动,但我所做的一切似乎都没有按照我的需要将数据发送到ARDrone

创建连接:

channel = DatagramChannel.open();
channel.configureBlocking(false);
channel.socket().bind(new InetSocketAddress(video_port));
channel.connect(new InetSocketAddress(drone_addr, video_port));

selector = Selector.open();
channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
这是当前的发送/接收数据功能

public void run() {
    try {
        ByteBuffer inbuf = ByteBuffer.allocate(BUFSIZE);
        done = false;
        while (!done) {
            selector.select();
        if (done) {
            disconnect();
            break;
        }
        Set readyKeys = selector.selectedKeys();
        Iterator iterator = readyKeys.iterator();
        while (iterator.hasNext()) {
            SelectionKey key = (SelectionKey) iterator.next();
            iterator.remove();
            if (key.isWritable()) {
                byte[] trigger_bytes = { 0x01, 0x00, 0x00, 0x00 };
                ByteBuffer trigger_buf = ByteBuffer.allocate(trigger_bytes.length);
                trigger_buf.put(trigger_bytes);
                trigger_buf.flip();
                channel.write(trigger_buf);
                channel.register(selector, SelectionKey.OP_READ);
            } else if (key.isReadable()) {
                inbuf.clear();
                int len = channel.read(inbuf);

                if (len > 0) {
                    inbuf.flip();
                    final BufferedVideoImage vi = new BufferedVideoImage();;
                    vi.addImageStream(inbuf);
                    drone.videoFrameReceived(0, 0, vi.getWidth(), vi.getHeight(), vi.getJavaPixelData(), 0, vi.getWidth());
                }
            }
        }

    } catch (Exception e) {
        drone.changeToErrorState(e);
    }
}

我相信你在第一次写这句话时就破坏了你的活动兴趣:

channel.register(selector, SelectionKey.OP_READ);
,这会将其重置为仅限
OP_READ

编辑0: 根据您的评论-是的,我认为您应该完全删除这一行,并且不要将读写案例视为备选方案。通常,套接字可以同时可读写。因此,现在发生的情况是写情况阻止了读情况,因为UDP套接字始终是可写的(而TCP缓冲传出数据)

因此,我的建议是根本不要将
OP_WRITE
包含在该事件集中,而是以其他方式处理写入,比如在计时器上、每次读取后,或者任何对应用程序有意义的方式


希望这有帮助。

套接字是否在while循环中的某个位置阻塞?@ethrbunny我不知道它是如何阻塞的,尤其是如果我使用channel.configureBlocking(false);当我打开频道的时候。如果我将该代码添加到主帖子中可能会有所帮助,我现在就这么做。是的,这是真的,但是,将其更改为同时注册读取和写入似乎会使无人机在第一次连接后根本不提供任何数据。我应该完全删除该线路吗?我刚刚发现,通过移动该线路,连接的开始将不会被发送。当第一个字节写入套接字时(如果可写,会发生什么情况),它会触发无人机发送数据。因此,删除它将使它永远不会发送数据。删除OP_写入线会使无人机立即断开连接,正如我刚刚发现的。在向选择器注册之前发送第一个数据包。在注册之前已经发送了。或者你是说上层代码块中同时具有读/写功能的寄存器?我不明白。等待到底是什么?上层的一切不都会立即执行吗?或者是一个暂停直到连接?