2

简单地说,我能够从连接的套接字接收数据,直到它启动后大约 10 秒。解决此问题的解决方案是将数据发送到“客户端”(ARDrone)以保持数据流继续运行,否则它将停止向手机发送数据。但是,由于某种原因,我当前的代码仅在第一次连接时将数据写入客户端(ARDrone),之后再也不写入。即使在套接字通信之后,我也需要它继续向 ARDRone 发送数据。

我已经尝试过移动channel.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);
    }
}
4

1 回答 1

3

我相信你在第一次写这行时破坏了你的事件兴趣:

channel.register(selector, SelectionKey.OP_READ);

根据文档,这会将其重置为OP_READonly。

编辑0:

根据您的评论 - 是的,我认为您应该完全删除该行,并且不要将读写案例视为替代方案。一般来说,一个套接字可以同时是可读和可写的。所以现在发生的是写情况阻止了读情况,因为 UDP 套接字总是可写的(与缓冲传出数据的 TCP 相比)。

所以我的建议是根本不包括OP_WRITE在那个事件集中,而是以其他方式处理写入,比如在计时器上,或者在每次读取之后,或者对你的应用程序有意义的任何事情。

希望这可以帮助。

于 2011-07-13T20:46:37.360 回答