Java:如果 UDP 数据包在 socket.receive() 调用之间到达,会发生什么情况?

Java: What happens if a UDP packet arrives in-between calls to socket.receive()?

对于我的联网 Java 应用程序,我在系统级 DatagramSocket 上编写了一个线程安全的非阻塞 i/o 包装器。但是,我对某些事情感到困惑。如果 callback.onDataReceived() 正在执行时有新数据包进来会怎样?数据包是否被丢弃?它是否被添加到 OS 级队列并在循环的下一次迭代中被添加到 "received"?如果是这样,该队列是否有最大大小?

    /*
     * Receiving thread
     */
    rxThread = new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            byte[] incomingBuffer = new byte[DataConstants.NUM_BYTES_IN_DATAGRAM_PACKET_BUF];

            while (!Thread.currentThread().isInterrupted())
            {
                DatagramPacket incomingPacket = new DatagramPacket(incomingBuffer, incomingBuffer.length);
                try
                {
                    basicSocket.receive(incomingPacket);

                    callback.onDataReceived(
                            DatatypeUtil.getNBytes(incomingPacket.getData(), incomingPacket.getLength()),
                            incomingPacket.getAddress());
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    });

关于发生的 OS 级缓冲,您是正确的,您可以使用 API 方法 DatagramSocket.setRecieveBufferSize() and DatagramSocket.getRecieveBufferSize() 来操纵缓冲区的大小。

但是

也有可能丢失一些数据包,因为如果缓冲区溢出或数据包在传输过程中丢失,您的 UDP 数据包可能会被丢弃。毕竟 UDP 是一种无连接协议。如果您确实需要确保所有数据包都安全且完好无损,您可以切换到 TCP。

回到你的问题,如果碰巧 callback.onDataReceived() 需要更长的时间来执行,发送方正在发送数据包并且你的 UDP 缓冲区已满,那么你可能会开始丢失数据包