1

大家好!
我正在开发java UDP服务器。我将大量数据发送到我的服务器,并且由于接收缓冲区大小较小而丢失了部分传入数据包。现在我正在以这种方式设置接收缓冲区 -

DatagramChannel serverChannel;
serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024*1024*10); // 10 MB


是否有意义?此代码没有解决丢包问题。我的操作系统 - 64 位 Windows 7。

还有一个问题——我的网络控制器的接收缓冲区属性默认为 512——是字节还是兆字节?如果它是 512字节,是否需要手动增加此属性?我认为以编程方式增加缓冲区实际上会增加操作系统缓冲区,但这没有意义,因为最初 udp 数据包“来到”我的网卡。

4

3 回答 3

3

我将大量数据发送到我的服务器,并且由于接收缓冲区大小较小而丢失了部分传入数据包。

你不知道。有很多可能的原因。

现在我正在以这种方式设置接收缓冲区 -

DatagramChannel serverChannel;
serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024*1024*10); // 10 MB

是否有意义?

并非如此,这是一个巨大的缓冲区,操作系统可能会将其截断为更合理的大小。设置后尝试获取该选项并查看实际大小。

此代码没有解决丢包问题。

没有人说会。你只是假设它。

还有一个问题——我的网络控制器的接收缓冲区属性默认为 512——是字节还是兆字节?

在您告诉我们您使用的是什么 NIC 之前,没有人可以回答这个问题,但是您应该能够从制造商的数据中自己发现这一点。

如果它是 512 字节,是否需要手动增加此属性?

不仅没有必要,而且不可能。

我认为以编程方式增加缓冲区实际上会增加操作系统缓冲区

如果您SO_RCVBUF的意思是控制套接字接收缓冲区的大小,那是正确的。

但这没有意义

是的,它确实。

因为最初 udp 数据包“来”到我的网卡。

然后从那里进入操作系统,从那里进入 IP 堆栈,从那里进入 UDP 堆栈,再从那里进入套接字接收缓冲区。当大多数路径 MTU 高达 1500 字节时,NIC 似乎不太可能有 512 字节的缓冲区,但例如 512k 确实有意义。你可以假设它已经足够了,毕竟它确实有效。

你的基本假设是有缺陷的。UDP 数据包可能因多种原因而丢失:它们从未被发送,它们被中间路由器丢弃,它们被分段并且并非所有分段都到达接收器,或者接收器的套接字接收缓冲区已满,这反过来可能是因为它太小,也可能是因为接收者跟不上发送者。仅仅使用一个巨大的套接字接收缓冲区只能解决这些问题之一。如果您需要可靠性,请使用 TCP,或者通过重试实现 ACK 或 NACK 机制。

于 2013-03-18T03:48:12.623 回答
1

是否有意义?

有点儿。但是,您无法保证 UDP 数据包不会丢失。UDP本质上是一种不可靠的协议。如果您的应用程序无法以足够快的速度从套接字中拉出数据包以跟上速度,或者如果出现网络错误,数据包将会丢失。

如果您需要将数据可靠地发送到您的服务器,您可能应该使用 TCP ...

我的网络控制器的接收缓冲区属性默认为 512 - 它是字节还是兆字节?

我不知道,但我也不怀疑。它更有可能是千字节。


我试图增加控制器的缓冲区大小 - 操作系统说 512 是最大可能的)

那么,您将无法将其增加到 10Mb。

因此,如果没有 newtwork 错误,我的数据包只会在我处理它们太慢的情况下丢失。

不完全是。由于各种原因,数据包可能会在许多地方丢失/丢弃。其中一些是“正常行为”而不是“网络错误”;例如,当路由器/网桥/网关拥塞时丢包。

增加缓冲区大小看起来足以解决问题,但令人惊讶的是它失败了。

事实上,这并不奇怪。丢包可能是正常行为;往上看。

可能我应该在一个线程中接收数据包并在另一个线程中处理它们,即使我使用专门用于开发“单线程”服务器的 java NIO。

它可能有助于减少操作系统和网络接口中的数据包丢失。但是,您最终会在应用程序内存中缓冲数据,这可能会导致更严重的问题……如果应用程序无法长期跟上。

此外,它不处理因其他原因丢失/丢弃的数据包。


底线是您将无法使用 UDP 实现可靠的无损传输。丢包是不可避免的,您正在浪费时间试图避免它。

您要么必须设计应用程序来处理丢失的数据报,要么改用 TCP 或其他提供可靠数据传输的协议。

于 2013-03-18T03:42:20.100 回答
1

UDP 发送/接收离散数据包;最大大小约为 65K。如果您要发送的数据比这更多,则需要将其分成多个数据包。正如其他人所指出的,UDP 是一种不可靠的协议。数据包可能会消失、重复或乱序接收。

于 2013-03-18T03:48:31.683 回答