c# - UDP数据传输比TCP慢

标签 c# .net sockets tcp udp

我目前正在 C#/.Net4 中编写一个原型(prototype)应用程序,我需要传输未知量的数据。数据从文本文件中读入,然后序列化为字节数组。 现在我需要实现两种传输方法:UDP 和 TCP。两种方式的传输都工作正常,但我在 UDP 方面遇到了一些困难。我假设使用 UDP 的传输必须比使用 TCP 快得多,但实际上我的测试证明 UDP 传输比使用 TCP 慢大约 7 到 8 倍。 我用12兆字节的文件测试了传输,TCP传输大约需要1秒,而UDP传输大约需要7秒。 在应用程序中,我使用简单的套接字来传输数据。由于 UDP 只允许每条消息最大为 65535kb,因此我将文件的序列化字节数组分成几个部分,其中每个部分都有 socker SendBufferSize 的大小,然后使用 Socket.Send() 方法调用传输每个部分。

这是发送者部分的代码。

while (startOffset < data.Length)
{
    if ((startOffset + payloadSize) > data.Length)
    {
        payloadSize = data.Length - startOffset;
    }
    byte[] subMessageBytes = new byte[payloadSize + 16];
    byte[] messagePrefix = new UdpMessagePrefix(data.Length, payloadSize, messageCount, messageId).ToByteArray();
    Buffer.BlockCopy(messagePrefix, 0, subMessageBytes, 0, 16);
    Buffer.BlockCopy(data, startOffset, subMessageBytes, messageOffset, payloadSize);
    messageId++;
    startOffset += payloadSize;
    udpClient.Send(subMessageBytes, subMessageBytes.Length);
    messages.Add(subMessageBytes);
}

此代码只是将要发送的下一部分复制到字节数组中,然后调用套接字上的发送方法。我的第一个猜测是,字节数组的分割/复制会降低性能,但我隔离并测试了分割代码,分割只花了几毫秒,所以这不会导致问题。

int receivedMessageCount = 1;
Dictionary<int, byte[]> receivedMessages = new Dictionary<int, byte[]>();
while (receivedMessageCount != totalMessageCount)
{
    byte[] data = udpClient.Receive(ref remoteIpEndPoint);
    UdpMessagePrefix p = UdpMessagePrefix.FromByteArray(data);
    receivedMessages.Add(p.MessageId, data);
    //Console.WriteLine("Received packet: " + receivedMessageCount + " (ID: " + p.MessageId + ")");
    receivedMessageCount++;
    //Console.WriteLine("ReceivedMessageCount: " + receivedMessageCount);
}
Console.WriteLine("Done...");
return receivedMessages;

这是我接收 UDP 消息的服务器端代码。每条消息都有一些字节作为前缀,其中存储消息总数和大小。因此,我只需循环调用 socket.Receive ,直到收到前缀中指定的消息数量。

我在这里的假设是,我可能已经实现的 UDP 传输代码不够“高效”...也许你们中的一个人已经在代码片段中发现了问题,或者对我有任何其他建议或提示,为什么我的 UDP 传输比 TCP 慢。

提前致谢!

最佳答案

虽然 UDP 数据报大小可达 64K,但实际线帧通常为 1500 字节(正常以太网 MTU )。它还必须适合至少 20 字节的 IP header 和 8 字节的 UDP header ,从而为您留下 1472 字节的可用负载。

您所看到的是操作系统网络堆栈的结果 fragmenting发送方的 UDP 数据报,然后在接收方重新组装它们。这需要时间,因此也需要你的结果。

另一方面,TCP 会进行自己的打包并尝试查找 path MTU ,因此在这种情况下效率更高。

将数据 block 限制为 1472 字节并再次测量。

关于c# - UDP数据传输比TCP慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9300555/

相关文章:

c# - 枚举类型在 C# 中存储为 int 吗?

c# - 有没有办法使用币安 API 获取代币的市值或市值排名?

.NET 成员(member)资格 - 注册、登录等工作。密码重置没有

ios - 在 iOS 中使用 NSHost

c - 如何修复 :UDP packet send through vlan(eth0. 4092),到达 eth0 和 eth0.4092

c# - 如何在 C# 中获取该目录中最后修改的特定 TYPE 文件的日期和时间

c# - 设置输入到波形文件

C# 从 DataGridView 中删除行并更新数据库

c# - ClosedXML 返回文件

Java 套接字 : Read/receive the same instance multiple times after change values: ObjectInputStream. readObject()