不稳定的tcp接收时间

时间:2011-12-23 15:37:35

标签: python linux sockets tcp

我正在使用套接字编写客户端,以便从录制PC(RP)接收EEG数据,以产生一些在线反馈。

RP有一个通过TCP发送数据的服务器。数据与块一起发送,每个块都有一个头和数据(总共是2560字节)。每 20 ms (50 Hz)发送块。

当我运行客户端时,它会接收突发中的块(例如, 40ms 的一个块,然后是下一个, 0ms )。首先我认为这是因为服务器使用Nagle算法并且数据包很小而无法单独发送,但是当我将块大小减小到400字节时,recv()返回时间变得更加稳定(现在大约20ms)。一些变化,但没有爆发)。即使使用2.5k数据包,所需的总带宽也不会很大:50 * 2560 = 128 kB / s。当我在localhost上运行客户端和服务器时,存在相同的不稳定性。这可能是什么问题?

Herer是(简化的)客户端代码:

# ...
# 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

UPD:我与wireshark检查了对话。问题似乎在客户端:它仅在最后一个服务器的[PSH,ACK] 40ms后发送[ACK]数据包(服务器几乎立即响应客户端的[ACK])。服务器已经获得了2个数据包,因此它发送了2个胶合数据包。问题仍未解决:(

PS:我正在使用带有2.6.35内核的Ubuntu

2 个答案:

答案 0 :(得分:1)

你可以尝试通过以下方式禁用Nagle:

  

可能使用

    sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
     

将帮助您按需发送每个数据包,因为这会禁用Nagle's algorithm   TCP堆栈使用它将几个小型数据的数据包连接在一起(并且通过   默认我相信)

正如https://stackoverflow.com/a/647835/1132184

中所建议的那样

答案 1 :(得分:0)

TCP是基于流的。永远不能保证您将完全按照发送的方式收到所有内容。使用UDP(但UDP并不保证一切都到达或者所有内容都以与发送时相同的顺序到达。)

除此之外,按照建议禁用nagle,因为它会对发送的消息进行排队,以减少TCP标头为小包添加的开销。