数据报通道套接字不写 Java

Posted

技术标签:

【中文标题】数据报通道套接字不写 Java【英文标题】:Datagram Channel Sockets not writing Java 【发布时间】:2011-10-04 15:06:37 【问题描述】:

简单地说,我能够从连接的套接字接收数据,直到它启动后大约 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);
    

【问题讨论】:

套接字是否在 while 循环中的某处阻塞? @ethrbunny 我不明白它是怎么做到的,特别是如果我使用 channel.configureBlocking(false);当我启动频道时。如果我将该代码添加到主帖子中可能会有所帮助,我现在将这样做。 【参考方案1】:

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

channel.register(selector, SelectionKey.OP_READ);

Per documentation,这会将其重置为仅OP_READ

编辑0:

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

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

希望这会有所帮助。

【讨论】:

是的,确实如此,但是,将其更改为同时注册读取和写入似乎会使无人机在第一次连接后根本不提供任何数据。我应该完全删除那条线吗? 我刚刚发现通过移动线路,将不会发送连接的开始。当第一个字节被写入套接字时(如果它是可写的会发生什么),它会触发 Drone 发送数据。所以删除它会使它永远不会发送数据。正如我刚刚发现的那样,仅删除 OP_WRITE 行会使 Drone 立即断开连接。 在向选择器注册之前发送您的第一个数据包。 注册前已发送。或者你的意思是上层代码块中的寄存器,它同时具有读/写功能? 我不明白。究竟是什么等待?顶部的所有内容不会几乎立即执行吗?还是在连接前暂停?

以上是关于数据报通道套接字不写 Java的主要内容,如果未能解决你的问题,请参考以下文章

如何在同一本地/src 地址上创建多个 UDP 数据报通道/流

Java - 异步套接字通道无法连接到远程异步服务器套接字通道

java数据报套接字的文件描述符

Java-API DatagramSocket 数据报套接字 类

带有 Java 客户端和 Python 服务器的数据报套接字

Java NIO套接字通道