使用 C# 在 Linux 防火墙后面接收大型 UDP 数据包失败

Receiving large UDP packet fails behind Linux firewall using C#

我在家用电脑上成功使用了这段代码 - 请注意,我已缩小代码以便仅显示重要部分

Socket Sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

// Connect to the server
Sock.Connect(Ip, Port);

// Setup buffers
byte[] bufferSend = ...; // some data prepared before
byte[] bufferRec = new byte[8024];

// Send the command
Sock.Send(bufferSend, SocketFlags.None);

// UNTIL HERE EVERYTHING WORKS FINE

// Receive the answer
int ct = 0;
StringBuilder response = new StringBuilder();
while ((ct = Sock.Receive(bufferRec)) > 0)
{
     response.Append(Encoding.Default.GetString(bufferRec, 0, ct));
}

// Print the result
Console.WriteLine("This is the result:\n" + response.ToString());

在另一个环境中(Windows 但在 Ubuntu 防火墙后面)我在接收超过 1472 字节的数据包时遇到问题:抛出请求超时的异常。

所以基本上我有两个选择:

我需要如何调整我的代码才能按工作大小拆分数据包?我认为调整变量 bufferRec = new byte[1024] 就足够了,但显然这是行不通的。然后我得到一个异常,接收到的包大于 bufferRec。我必须更改 SocketType 吗?

很遗憾,我对套接字知之甚少,所以您的解释会很有帮助!

您的数据包正在各种网络中传输。每个网络可能都有自己的 MTU 大小。这是单个数据包的最大尺寸。

如果您的数据超过该大小,则会检查 DF 标志(DF 代表不分段)。如果设置了该标志,则会丢弃数据包并生成 ICMP 响应。

在 C# 套接字中,此选项由 DontFragment 属性 控制,默认为 True,因此您的问题。

请注意,启用分段的 UDP 被认为是不可靠的,因为数据包可能会在繁忙的网络上丢失