为什么TCP / IP速度取决于发送数据的大小?

时间:2017-02-17 05:21:54

标签: linux sockets tcp winsock ethernet

当我连续发送小数据(16字节和128字节)时(使用没有任何插入延迟的100次循环),TCP_NODELAY设置的吞吐量似乎不如正常设置。另外,TCP-slow-start似乎在开始时影响传输。

enter image description here

enter image description here

原因是我想通过以太网从PC控制设备。该设备的处理时间约为几微秒,但发送命令的巨大延迟影响了整个系统。你能和我分享一些解决这个问题的方法吗?提前谢谢。

上次,我测量了Windows-PC和Linux嵌入式主板之间的传输性能。为了验证TCP_NODELAY,我设置了一个系统,其中两台Linux PC彼此直接连接,即Linux PC< - >。路由器< - > Linux PC。该路由器仅用于两台PC。

没有TCP_NODELAY的性能如下所示。当数据大小> = 64KB时,很容易看出吞吐量显着增加。此外,当数据大小= 16 B时,有时接收时间下降到4.2 us。你对这个观察有什么看法吗?

enter image description here

TCP_NODELAY的性能似乎没有变化,如下所示。

enter image description here

完整代码可在https://www.dropbox.com/s/bupcd9yws5m5hfs/tcpip_code.zip?dl=0

中找到

请与我分享您的想法。提前谢谢。

我正在进行套接字编程,以便在Windows 10 PC和Linux嵌入式主板之间传输二进制文件。套接字库分别是针对Windows和Linux的winsock2.h和sys / socket.h。二进制文件在发送之前复制到Windows中的数组,接收的数据存储在Linux中的数组中。

Windows:socket_send(sockfd,& SOPF-> array [0],n);

Linux:socket_recv(& SOPF-> array [0],connfd);

我可以正确接收所有数据。但是,在我看来,传输时间取决于发送数据的大小。当数据量很小时,接收的吞吐量非常低,如下所示。

enter image description here

你能告诉我一些解释这个问题的文件吗?提前谢谢。

3 个答案:

答案 0 :(得分:3)

要建立tcp连接,您需要3次握手:SYN,SYN-ACK,ACK。然后发件人将开始发送一些数据。多少取决于初始拥塞窗口(可在Linux上配置,不知道在Windows上)。只要发送方及时接收到ACK,它就会继续发送,只要接收方通告窗口有空间(使用套接字选项SO_RCVBUF来设置)。最后,关闭连接还需要FIN,FIN-ACK,ACK。

所以我没有更多信息的最佳猜测是,设置和拆除TCP连接的开销会对发送少量字节的开销产生巨大影响。只要作者有效地快速写入,Nagle的算法(禁用TCP_NODELAY)就不会有太大的影响。它只能防止发送少于完整的MSS分段,这会增加传输效率,在这种情况下,发送方只是尽可能快地发送数据。我能看到的唯一影响是,最终不到完整的MSS段可能需要等待ACK,与较长的传输相比,这对短传输也会产生更大的影响。

为了说明这一点,我在我的环回接口上使用netcat(nc)发送了一个字节(这不是物理接口,因此带宽是&#34;无限&#34;):< / p>

$ nc -l 127.0.0.1 8888 >/dev/null &
[1] 13286
$ head -c 1 /dev/zero | nc 127.0.0.1 8888 >/dev/null

以下是wireshark中的网络捕获:

enter image description here

总共需要237微秒才能发送一个字节,这个数字是4.2KB /秒。我想你可以猜到,如果我发送了2个字节,那么实际上需要相同的时间才能达到8.2KB /秒的有效速率,100%的改进!

诊断网络性能问题的最佳方法是获取网络捕获并进行分析。

答案 1 :(得分:1)

TCP套接字通常在内部具有缓冲区大小。在许多实现中,它将在发送数据包之前等待一段时间,以查看它是否可以在发送之前填满缓冲区中的剩余空间。这称为Nagle's algorithm。我假设您上面报告的时间不是由于TCP数据包中的开销,而是由于TCP在实际发送之前等待您排队更多数据。

因此,大多数套接字实现都有一个名为TcpNoDelay的参数或函数,它可以是false(默认值)或true。我会尝试弄乱它,看看是否会影响你的吞吐量。基本上这些标志将启用/禁用Nagle的算法。

答案 2 :(得分:1)

当您使用大量数据进行测试时,例如更大的测试(512Mib,536百万字节),会发生以下情况。

数据由TCP层发送,在一定长度的中断开。假设1460字节的段,因此将有大约367,000个段。

对于传输的每个段,都有一个开销(控制和管理添加数据以确保良好的传输):在您的设置中,TCP有20个字节,IP有20个,以太网有16个,总共56个字节< strong>每个细分。请注意,这个数字是最小,而不是以太网前导码为例;此外,有时IP和TCP开销可能会更大,因为可选字段。

那么,每个段56个字节(367,000个段!)意味着当您传输512Mib时,您还可以在线路上传输56 * 367,000 = 20M字节。总字节数变为536 + 20 = 556百万字节,或4.448百万位。如果将此位数除以经过的时间(4.6秒),则会得到每秒966兆比特的比特率,这高于您未计算的开销。

从上面的演算中,您的以太网似乎是千兆位。它的最大传输速率应该是每秒1000兆比特,你真的很接近它。剩下的时间是由于我们没有考虑到更多的开销,并且一些延迟总是存在并且随着更多数据的传输而倾向于被取消(但它们永远不会被彻底击败)。

我会说你的设置还可以。但这是用于大数据传输。随着传输大小的减少,数据的开销,协议的延迟和其他好处变得越来越重要。例如,如果您在165微秒(第一次测试)中传输16个字节,则结果为0.78 Mbps;如果花费4.2 us,减少约40倍,则比特率约为31 Mbps(大40倍)。这些数字低于预期。

实际上,你不传输16个字节,你传输至少16 + 56 = 72个字节,这是4.5倍,所以链路的实际传输速率也更大。但是,你看,在TCP / IP链路上传输16个字节与通过丢弃一些水滴来测量空洞的流量是相同的:眼泪在到达另一端之前就会丢失。这是因为TCP / IP和以太网旨在承载更多数据,具有可靠性。

本页面中的评论和答案指出了许多交易比特率和可靠性反应性的机制:3路TCP握手,Nagle算法,校验和和其他开销,等等。

考虑到TCP + IP和以太网的设计,对于很少的数据,性能不是最佳的是非常正常的。从您的测试中可以看出,当数据大小达到64K字节时,传输速率会急剧上升。这不是巧合。

根据您在上面留下的评论,您似乎正在寻找低延迟通信,而不是带宽较大的通信。混淆不同类型的表演是一个常见的错误。而且,就此而言,我必须说TCP / IP和以太网完全是非确定性的。当然,它们很快,但是没有人可以说多少,因为它们之间的层数太多了。即使在您的简单设置中,如果单个数据包丢失或损坏,您也可以预期延迟,而不是微秒。

如果你真的想要低延迟的东西,你应该使用别的东西,例如CAN。它的设计正是您想要的:它以高速,低延迟,确定性时间传输少量数据(传输数据包后仅几微秒,您知道是否已收到。) exact:恰好在数据包传输结束时你知道,如果它到达目的地了。)