我正在阅读有关TCP数据stream, 延迟ACK和Nagle的algorithm 。
到目前为止我明白:
在一些交互式应用程序中,比如Rlogin, Nagle的algorithm和延迟应答可以“冲突”:
当我们input键盘input时,Rlogin会将键盘input发送到服务器,并且一些键(如F1 )会生成多个字节( F1 = Escape +左括号+ M)。 如果将这些字节逐个传递给TCP,则可以将这些字节发送到不同的段中。
服务器没有回应,直到它有整个序列,所以所有的ACK将被延迟(期待从应用程序的一些数据)。 另一方面,客户端会在发送下一个字节之前等待第一个字节的确认(尊重Nagle的algorithm )。 这种组合最终导致了“laggy”Rlogin。
在Rlogin上发送的F1和F2密钥的tcpdump如下所示:
type Fl key 1 0.0 slip.1023 > vangogh. login: P 1:2(1) ack 2 2 0.250520 (0.2505) vangogh.login > slip.1023: P 2:4(2) ack 2 3 0.251709 (0.0012) slip.1023 > vangogh.login: P 2:4(2) ack 4 4 0.490344 (0.2386) vangogh.login > slip.1023: P 4:6(2) ack 4 5 0.588694 (0.0984) slip.1023 > vangogh.login: . ack 6 type F2 key 6 2.836830 (2.2481) slip.1023 > vangogh.login: P 4:5(1) ack 6 7 3.132388 (0.2956) vangogh.login > slip.1023: P 6:8(2) ack 5 8 3.133573 (0.0012) slip.1023 > vangogh.login: P 5:7(2) ack 8 9 3.370346 (0.2368) vangogh.login > slip.1023: P 8:10(2) ack 7 10 3.388692 (0.0183) slip.1023 > vangogh.login: . ack 10
现在怀疑:尽pipe我读到的页面表明服务器在它具有整个密钥序列之前没有回应回应,但是通过tcpdump捕获的数据包显示密钥在它们各自的ACK上被回显(第一个回复是2个字节,因为来自ESC的回声是两个字符 – caret +左括号。
如果数据正在从应用程序发送到TCP(回应响应),为什么ACK被延迟? 根据所述,关于服务器在回应之前等待完整序列 ,是不是ACK应该不包含到最后一个ACK的回声,这将包含整个序列回声?
参考: http : //people.na.infn.it/~garufi/didattica/CorsoAcq/Trasp/Lezione9/tcpip_ill/tcp_int.htm
你说rlogin“服务器没有回应回应,直到它具有整个序列”,如通常^[OP键为F1键。 但这只是一个无理的假设。 而一个错误的。 而你的tcpdump实验显示情况并非如此; 它显示了完全没有任何“优化”的落后的rlogin实现。
事实上,服务器的正常预期行为是立即回应任何input。 如果客户因为某种原因决定发送^[单独的,那么在这之后不会经历一个奇怪的延迟(完全抛开TCP)。
对于laggy-rlogin类问题应该是一个干净的解决scheme,每一个对话( 客户端和服务器端)都只send()当他们真正相信在这个时刻某个人正在等待显示的结果。 在这样的约束下,发送给客户端的一个主要的错误是^[当软件已经知道, ^[OP是完整的预期序列,并且人类用户对完整结果感兴趣,而不仅仅是^[一个人决定发送OP还是OQ ,或者是什么?)。
所以,对于软件开发人员来说,反直觉的build议是什么,无论他们的业务是使用TCP还是开发客户端或服务器端:记住send()不是立即的,它可能会延迟下一次传输,所以更仔细地使用它Nagle添加延迟的结果延迟ACK添加更多的延迟)。
AFAIK Nagle的algorithm设置在非常低的套接字configuration。 例如,套接字通信的C / C ++实现使用相当低级别的API来closures它。
Nagle的想法在TCP / IP的典型用法上是相当不错的。
例如,我们一直使用软实时系统的一些消息库,并且我们已经明确地在套接字级closures了它。 正是这个原因。 我们不想等。 使用Nagle的套接字等待,直到完整的缓冲区已满 – 不pipe消息的types如何。 所以ACK被延迟,因为它们全部都很小,缓冲区将缓慢地满。
但实际提示如下:1.closuresNagle的algorithm或2.如果你不能,那么发送更大的消息,所以Nagle的缓冲区通常是满的。