开发者

Datagram Channel Sockets not writing Java

Simply said, I'm able to receiv开发者_运维知识库e data from the connected socket, until about 10 seconds after it starts. The solution to fix this is, to send data to the 'client'(an ARDrone) to keep the data stream going, otherwise it will stop sending data to the phone. However, my current code for some reason only writes data to the client (the ARDrone) on first connect and never after. I need it to keep sending data to the ARDrone even after the socket is communicating.

I've tried moving around the channel.register() calls, but nothing I've done seems to send data to the ARDrone, as I need.

Creating the connection:

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

Here is the current send/receive data function.

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


I believe you corrupt your event interest on the first write with this line:

channel.register(selector, SelectionKey.OP_READ);

Per documentation, this resets it to OP_READ only.

Edit 0:

Per your comment - yes, I think you should remove that line entirely, and do not treat read and write cases as alternatives. In general a socket could be readable and writable at the same time. So what's happening now is that the write case prevents the read case since UDP socket is always writable (versus TCP that buffers outgoing data).

So my suggestion is to not include OP_WRITE into that event set at all, but handle writing in some other fashion, say on a timer, or after each read, or whatever makes sense to your app.

Hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜