17-TCP 协议(迟到的 ACK —— Windows )
[复制链接]
1. 引言我们知道,TCP 协议中,需要对接收到 TCP 段进行确认。有两种方式可以减少 TCP 报文段. 一种是累积确认,另一种是捎带确认。 有时候,发送方发送速度非常快,接收方一下下接收到了好几个 tcp 段,可以通过累积确认的方式,一次确认好几个 tcp 段,这样减少报文段的传输。 有时候,双方互相发送数据,当接收到对方的 tcp 段后,先不着急确认,而是等待一会儿,连同数据和 ack 一起发送过去,这种情况叫捎带确认。如果等了一会儿(到时间了),接收方还没有数据要发送,那就直接回复一个纯 ack 过去,这样的 ack 称为延时的 ack(Delayed ACK). 本文就来看一下,操作系统是如何进行时延确认的。 2. 实验本节实验,我们使用新的客户端 echo_client.cpp 和 新的服务器 echo_serv.c. - 客户端:unp/protocol/tools/winclient/echo_client.cpp,部署在 Windows 上。
- 服务器:unp/protocol/tools/tcpserver/echo_serv.cpp,部署在 Linux 上。
echo_serv 的功能是将接收到数据回射回去。echo_client 的功能是从键盘接收字符,每接收到一个字节就立即发送出去。 当 echo_client 连接到 echo_serv 的时候,在键盘上键入字符,echo_client 会将键入的字符立即发送到服务器,然后服务器将收到的字符回送回来。echo_client 接收到回送的字符后,将其打印到屏幕。 特别注意的是,echo_client 启动后,从键盘键入字符,是不会显示在屏幕上的。这个功能是由函数 getch 完成的,如果不太明白,建议先 baidu or google 一下这个函数。 2.1 实验步骤$ echo_serv 192.168.80.130 8000- Windows 端打开 OmniPeek 进行抓包,然后启动 echo_client
$ echo_client 192.168.80.130 8000然后分别键入 loveq 这五个字符,一定记得,是五个字符,最后一个字符 q 不要丢了!!!
图1 键入 loveq
可以看到显示了 love,因为这四个字符是服务器发送回来的。而键入的 q 直接导致了客户端退出。 2.2 抓包结果
图2 抓到的数据包
先来分析一下,4 号数据包,客户端给服务器发送了字符 l,服务器直接回送了 5 号数据包 ack. 详细情况见图 3. 注:数据包序号标注有点问题,不要以图 2 最左右的序号来看,实际序号就是从 1 开始,即 packet 2 实际上是 1 号,packet 8 实际上是 4 号数据包。
图3 延时的 ACK
然后,服务器紧接着又将收到的数据发给了客户端(6号包)。 7 号包对服务器发来的 6 号包进行确认. 此后,我们看到所有客户端对服务器回显的数据进行确认,都是只有 ack 而没有携带数据,因为你在输入l、o、v、e 的时候很慢很慢的,客户端等不及你输入数据就先把 ack 发过去了。 客户端有没有等你的数据呢?实际上是有的,看图 2 中红框,这个 Delta Time 表示相对上一个数据包的时间,我们可以发现这个时间基本上都是 200 ms 左右。 也就是说,如果 tcp 在等待了约 200ms 左右,还是没有数据要发送,就把这个 ack 单独发送出去了。(win10 系统测试现在是 40ms)。 以上是 windows 表现的结果,在 Linux 中又是另一番景象,下回分解。 3. 总结
|