对于我的联网Java应用程序,我在系统级DatagramSocket上编写了一个线程安全的,非阻塞的I / O包装器。但是,我对某些事情感到困惑。如果在执行callback.onDataReceived()
时有新的数据包进来怎么办?数据包被丢弃了吗?是否将其添加到操作系统级别的队列中,并在循环的下一次迭代中“接收”?如果是这样,该队列的大小是否最大?
/*
* 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();
}
}
}
});
答案 0 :(得分:1)
您对发生的操作系统级别缓冲是正确的,可以使用API方法DatagramSocket.setRecieveBufferSize()和DatagramSocket.getRecieveBufferSize()来操纵缓冲区的大小。
但是
也有可能丢失某些数据包,因为如果缓冲区溢出或数据包在传输中丢失,则UDP数据包可能会丢失。毕竟,UDP是无连接协议。如果确实需要确保所有数据包都是安全无损的,则可以切换到TCP。
回到您的问题,如果碰巧callback.onDataReceived()
花费了更长的时间执行,发送方正在泵送数据包并且您的UDP缓冲区已满,那么您可能会开始丢失数据包