2011-12-23 64 views
3

我正在写一个客户端,使用套接字接收来自录制PC(RP)的EEG数据以产生一些在线反馈。unstable tcp receive times

RP有一个通过TCP发送数据的服务器。数据正在发送块,每个块都有一个头和数据(全部是2560字节)。块每隔20 ms(50 Hz)发送。

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

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](服务器几乎在客户端的[ACK]上立即响应)后40ms后才发送[ACK]数据包。服务器已经获得了2个数据包,所以它发送了2个粘贴的数据包。现在的问题是开:(

PS:我使用Ubuntu与2.6.35内核

+1

我不是很擅长网络编程,但我相信问题出在服务器(和网络缓冲区相关)的某个地方。您是否尝试过运行网络嗅探器(我可以推荐wireshark)来检查网络层面发生了什么。 – rvs 2011-12-23 16:00:00

+0

可能是,但我已经尝试了两个不同的服务器实现本地和远程,并具有相同的模式。其实这是一个不错的主意,wirehark的事情,我会尝试。 – dmytro 2011-12-23 16:07:30

+0

看起来像是客户的问题。检查UPD – dmytro 2011-12-24 18:25:34

回答

0

TCP已建议是基于流的。从来没有保证您会收到您发送的所有内容。使用UDP(但UDP不保证一切到达或一切按照发送的顺序到达)。

除此之外,请按照建议禁用nagle,因为它会将发送的消息排队以减少发送的消息TCP头添加了小包。

+0

好吧,我只是留下它想到以下想法:“TCP不适用于实时系统” – dmytro 2012-03-27 22:09:25

+0

取决于时间窗口有多小,以成为一个实时系统,您可能需要使用UDP自己重新发送数据包,这可能需要比TCP中的内置功能更长的时间。 – jgauffin 2012-03-28 05:26:51

1

您可以尝试通过禁用纳格:

可能使用

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

将帮助发送每个数据包,因为这将禁用Nagle's algorithm,因为大多数 TCP堆栈使用它将几个小型数据包连接在一起(并且由开启默认我相信)

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

+0

是的,正如我在描述中所写的,我首先尝试了那个。没有很好的工作:( – dmytro 2012-02-05 12:20:50