如果我没有主动从DatagramSocket接收数据包,是否会丢弃数据包?

时间:2011-08-10 19:29:21

标签: java android sockets udp

我访问了很多网站和教程(和文档),但我还有一个问题没有答案。如果UDP数据包到达,当我当前没有运行socket.receive(...)时会发生什么?它会以某种方式缓冲,直到我调用socket.receive(...)或者它完全丢失了吗?

Android的DatagramSocket实现也是线程安全的,你可以在收听时写入套接字吗?

1 个答案:

答案 0 :(得分:9)

内核网络堆栈为每个套接字保留接收缓冲区。您可以使用SO_RCVBUF系统调用的setsockopt(2)选项来控制它的大小(您必须弄清楚它的Java API是什么)。

只要该缓冲区中有足够的空间,传入的数据包就会在内核中排队。应用程序在该特定时刻执行“接收”功能需要。如果应用程序没有足够快地对数据包进行出队(即读取),则缓冲区溢出并且内核开始丢弃数据包。在Linux(通常是Unix)上,您应该可以使用netstat -s命令查看数据包丢弃计数。

我还要注意,此缓冲区不是唯一可以丢弃数据包的地方。如果其NIC内存中没有足够的空间,硬件可能会丢弃数据包。然后,如果内核太忙而不处理其常规网络输入队列,则设备驱动程序可以丢弃数据包。你需要严重的消息率才能解决这个问题。

TCP试图通过完全排序来解决所有这些问题,并在必要时进行重传。 UDP,简单地“发送并忘记”,对于丢弃的数据包没有任何作用(除了在连接的UDP套接字上从第二个send(2)收到错误的极端情况,并且仅在{{3正常工作)。

底线是数据包被缓冲,但直到该点,然后被丢弃。