我正在尝试使用我在Raspberry Pi上开发并使用C ++编码的设备来测量通过以太网和串行端口进行数据传输的往返时间。我编写了一个C#程序,它一次向Raspberry Pi发送一个字节(波特率= 9600)并测量接收该字节所需的时间。在每个场景中,我都会在实际测试开始之前建立UDP或TCP连接。
以下是我的四个场景:
对于测试4,未使用Raspberry Pi设备;相反,计算机上带有C#测试程序的串口直接连接。
对于每个“以太网”部分,测试了UDP和TCP,这里是平均结果(超过数千个数据点 - 每次1000点的10次试验):
一个。串口到UDP:~5ms
湾串行到TCP:~62ms
串口到串口:~6ms
我很困惑为什么Serial to TCP与其他配置相比有如此大的延迟。此外,似乎总是发送的第一个字节的往返时间为4-5ms。之后,所有字节的RTT都为~62 ms。任何人都可以解释这一点或指向一个良好的资源?是否与流水线技术或串行和以太网之间的瓶颈有关?如果是这样,为什么我没有看到与Serial-UDP相同的现象?
UDP和TCP的代码基本上是相同的。如果您需要查看我可以上传的代码。
更新: 我仍然遇到这个问题。我试图在C ++ RPi服务器中禁用setsockopt到TCP_NODELAY,但这并没有真正改变时间。我还研究了使用NTP同步笔记本电脑和RPi之间的时间,但我也遇到了很多问题。例如,C#上的UTC毫秒分辨率似乎不够高。此外,我遇到与我的笔记本电脑和Rpi同步的问题,所以我不想走那条路。任何建议表示赞赏!
答案 0 :(得分:1)
您的用例是以最小延迟发送单个字节的TCP。这是一个简单的协议,应该根据您的用例优化TCP:
首先,不要禁用Nagle。其次,每次接收器接收到一些数据时,它应该发送一个应答字节。发送方应收到回复字节并将其丢弃。
接收方应尝试一次至少接收64个字节。无论它实际接收多少字节,它都应该发送一个字节作为回复。
这可以通过允许ACK捎带在应答字节上来稳定您的延迟。在绝大多数情况下,接收器将一次接收一个字节,但是您需要一种方法来从网络或CPU问题中恢复,而不是一个会被它们中断并且逐渐显示更糟糕行为的方案。
发件人永远不需要等待回复字节。它可以随时发送。