不稳定的TCP接收时间
我正在写一个客户端,通过套接字从一个记录电脑(RP)接收脑电图(EEG)数据,以便提供一些在线反馈。
这个记录电脑上有一个服务器,它通过TCP协议发送数据。数据是以块的形式发送的,每块都有一个头部和数据(总共2560字节)。这些数据块每20毫秒发送一次(也就是50赫兹)。
当我运行客户端时,它接收到的数据块是以突发的方式到达的(比如说,先接收到一个块用了40毫秒,然后下一个块几乎是立刻到达,0毫秒)。我开始以为这是因为服务器使用了Nagle算法,导致数据包太小,不能单独发送,但当我把块的大小减到400字节时,recv()的返回时间变得更加稳定(现在大约是20毫秒。虽然还有一些波动,但不再是突发了)。即使是2.5千字节的数据包,总带宽需求看起来也不大:50*2560 = 128 kB/s。在我同时在本地运行客户端和服务器时,也出现了同样的不稳定情况。这里可能是什么问题呢?
这是(简化版的)客户端代码:
# ...
# packet definitions as ctypes structures:
from protocol_defines import header, message
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((addr, port))
hdr = header() # 24 bytes
msg = message() # 2560 bytes
while True:
s.recv_into(hdr) # this thing should return once the hdr buffer is filled
# ... check if the message is ok ...
s.recv_into(msg) # this thing should return once the hdr buffer is filled
print time.time() # this is how I measure arrival times
更新:我用wireshark检查了数据传输情况。问题似乎出在客户端:它在上一个服务器的[PSH, ACK]之后要等40毫秒才发送[ACK]数据包(服务器几乎是立刻对客户端的[ACK]做出回应)。到那时,服务器已经收到了2个数据包,所以它发送了2个合并的数据包。这个问题仍然没有解决 :(
附注:我使用的是Ubuntu,内核版本是2.6.35
2 个回答
0
TCP是一种基于流的协议。这意味着你发送的数据不一定会完全按照你发送的顺序到达接收方。想要确保数据准确到达,可以使用UDP(不过UDP也不能保证所有数据都能到达,或者到达的顺序和发送时一样)。
除此之外,建议关闭Nagle算法,因为它会把发送的小消息排队,以减少TCP头部带来的额外开销。