第3章 TCP协议详解

第3章 TCP协议详解


3.1 TCP服务的特色

传输协议主要有两个:TCP协议和UDP协议,TCP协议相对于UDP协议的特色是html

  • 面向链接
    使用TCP协议通讯的双方必须先创建链接,完成数据交换后,通讯双方都必须断开链接以释放系统资源.算法

  • 字节流

    发送端执行的写操做次数和接收端执行的读操做次数之间没有任何数量关系.

    相比UDP则是发送端每执行一次写操做,UDP模块就将其封装成一个UDP数据报并发送之.为避免丢包,接收端必须及时针对每个UDP数据报执行读操做.编程

  • 可靠传输

    1) TCP协议采用发送应答机制,即发送端发送的TCP报文都获得了接收方的应答才算传输成功;

    2) TCP协议采用超时重传机制,即发送端在发送出一个TCP报文段后启动定时器,若在定时时间内未收到应答,将会重发该报文.缓存

TCP报文最终是以IP数据报发送的,而IP数据报的特色是无状态,无链接,不可靠的,即接收端可能收到乱序,重复的TCP报文段,因此TCP协议还会对接收到的TCP报文段进行重排与整理,再交付给应用层.服务器


3.2 TCP头结构

TCP头部信息出现每个TCP报文段中.markdown

0                   1                   2                   3   
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Data |           |U|A|P|R|S|F|                               |
| Offset| Reserved  |R|C|S|S|Y|I|            Window             |
|       |           |G|K|H|T|N|N|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             data                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • 16位源/目的端口号(Source Port&Destination Port) : 告知主机该报文来自哪里以及传给哪一个上层协议或应用程序.查看知名服务可以使用"cat /etc/services"网络

  • 32位序列号(Sequence Number) : 一次TCP通讯过程当中一个传输方向上的字节流的每一个字节的编号.假设主机A和B进行TCP通讯,A发送给B的第一个TCP报文段中,序列值被系统初始化为某个随机值ISN(Initial Sequence Number,初始序列号),那么在该传输方向上,后续的TCP报文段中序号值将被系统设置成ISN加上该报文段所携带数据的第一个字节在整个字节流中的偏移.并发

  • 32位确认号(Acknowledgment Number) : 用做对另外一方发送来的TCP报文段的响应.其值是收到的TCP报文段的序号加1.app

  • 4位头部长度(Data Offset) : 即该TCP头部有多少个32bit字.可见头部最大长度为60字节,包括Options部分.ssh

  • 6位标志位包含以下几项,能够为空

    URG: 表示紧急指针是否有效.

    ACK: 表示确认号是否有效,将拥有此标志的报文段称为确认报文段.

    PSH: 提示接收端应用程序应该当即从TCP接收缓冲区中读走数据.

    RST: 表示要求对方从新链接,将拥有此标志的报文段称为复位报文段.

    SYN: 表示请求一个链接,将拥有此标志的报文段称为同步报文段.

    FIN: 表示通知对方本端要关闭链接了,将拥有此标志的报文段称为结束报文段.

  • 16位窗口大小(Window) : TCP流量控制的一个手段.这里的窗口指的是接受通告窗口(Receiver Window,RWND).它告诉对方本端还能容纳多少字节的数据,以此对方就能够控制发送数据的速度.

  • 16位检码和(TCP checksum) :由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程当中是否损坏.检验内容包括TCP头部和数据部分.这是TCP可靠传输的一个重要保障.

  • 16位紧急指针(Urgent Pointer):其值为正的偏移量,它是发送端向接收端发送紧急数据的方法.

  • 选项部分(Options) : 是可变长的可选信息.这部分最多可包含40字节. 在这以前的全为固定部分,占用20字节的大小.

一.使用tcpdump观察TCP头部信息

pi@happyPi:~ $ telnet 127.0.0.1
IP 127.0.0.1.39681 > 127.0.0.1.23: Flags [S], seq 1470116583, win 43690, options [mss 65495,sackOK,TS val 2490119 ecr 0,nop,wscale 7], length 0
0x0000:  4510 003c cde0 4000 4006 6ec9 7f00 0001
0x0010:  7f00 0001 9b01 0017 57a0 32e7 0000 0000
0x0020:  a002 aaaa fe30 0000 0204 ffd7 0402 080a
0x0030:  0025 ff07 0000 0000 0103 0307
  1. 127.0.0.1.39681 > 127.0.0.1.23 表示从127.0.0.1的39681端口 发送至 127.0.0.1的23端口.

  2. Flags [S] 表示该TCP报文段包含SYN标志,所以是一个同步报文段.

  3. seq 1470116583 ,因为此报文是这个传输方向上第一个TCP报文段,因此这个序列号就是一个ISN.

  4. 因为是整个通讯过程当中的第一个TCP报文段,因此它没有针对对方发送来的TCP报文段的确认值.

  5. win 43690 , 表示接受通告窗口的大小,反映的是实际的接受通告窗口大小.

  6. mss(Max Segment Size,MSS) 65495 ,它是通讯双方协调最大报文段长度,通常会设置为(MTU-40)字节,40=20(IP头部)+20(TCP头部),从而避免发生IP分片,对于以太网来讲,MSS值是1460(1500-40)字节.

  7. sackOK : sack(Selective Acknowledgment,选择性确认)使得TCP模块只从新发送丢失的TCP报文段,不用发送全部未被确认的TCP报文段.

  8. wscale : wscale(window scale,窗口扩大因子)为了解决接收通告窗口过小的问题,由于接收窗口大小是用16位表示的,因此最大为65535(216-1)字节,但实际上TCP模块容许的接收通告窗口大小远不止这个数.若wscale为M,则表示实际接收通告窗口大小为N * 2M,N为win的大小.

二.对于TCP头部的解析:

0x0000:  4510 003c cde0 4000 4006 6ec9 7f00 0001
0x0010:  7f00 0001 9b01 0017 57a0 32e7 0000 0000
0x0020:  a002 aaaa fe30 0000 0204 ffd7 0402 080a
0x0030:  0025 ff07 0000 0000 0103 0307

因为TCP报文被IP协议封装过(IP头部大小为20字节),因此得从21字节开始看TCP的头部.

将IP头部的用"...."替换.

0x0000:  .... .... .... .... .... .... .... ....
0x0010:  .... .... 9b01 0017 57a0 32e7 0000 0000
0x0020:  a002 aaaa fe30 0000 0204 ffd7 0402 080a
0x0030:  0025 ff07 0000 0000 0103 0307
  • 9b01 : 对应源端口号39681.

  • 0017 : 对应目的端口号23.

  • 57a0 32e7 : ‭序号1470116583‬.

  • 0000 0000 : 确认号 0,tcpdump中未显示.

  • a : 10个32bit,即10*(32/8) = 40字节.

  • 002 : 将其去掉六位保留位,获得000002,标识码.

  • aaaa : 窗口大小‭43690‬.

可见TCP报文段头部的二进制和tcpdumTp输出的CP报文段描述信息彻底对应.

在后面的分析,将仅显示序号,确认号,窗口大小以及标志位等与讨论主题有关的字段.


3.3 TCP链接的创建和关闭

一. TCP链接的创建与三次握手

  1. 源机器对目标机器发起请求(seq:535734930 , Flags[S] , length 0)

  2. 目标机器收到请求,赞成与源机器链接,并回复给源机器(seq:2159701207 , Flags[S.] , ack:535734931 , length 0)

  3. 对目标机器回复的报文的确认(Flags[.] , ack:2159701208 , length 0).

这里值得注意的是原本seq(序列号)是用来标识TCP数据流中的每个字节的,可是同步报文段比较特殊,即便它并无携带任何应用程序数据,它也要占用一个序列值.

ack为确认号(Acknowledgment Number) , 其值为接收到的同步报文段的序列号加1.

以上三个步骤被称为TCP的三次握手.

二.TCP链接的关闭

  1. 源机器对已创建TCP链接的目标机器告之要关闭本链接(seq:535734931,ack:2159701208,Flags[F.],length 0)

  2. 目标机器收到通告,并发送确认信息.(ack:535734932 , length 0)

  3. 目标机器发送本身的结束报文段告之要关闭本链接(seq:2159701208,ack:535734932,Flags:[F.],length 0)

  4. 源机器发收到通告,并发送确认信息(ack:2159701209 , length 0).

通常而言,TCP链接是由客户端发起的,并经过三次握手创建(特殊状况是同时打开)的.

而TCP的关闭过程有这么几种可能:

  1. 多是客户端执行主动关闭,好比前面举的例子.

  2. 多是服务器执行主动关闭,好比服务器程序被中断而强制关闭链接.

  3. 多是同时关闭.

三.TCP链接的半关闭状态

因为TCP链接是全双工的,因此它容许两个方向(发送和接收)的数据传输被独立关闭.

于是通讯的一端能够发送结束报文段给对方,告之本端已完成数据的发送,但容许继续接收来自对方的数据,直到对方也发送结束报文段以关闭链接.

TCP的这种状态称之为半关闭状态(half close).

四.链接超时

对于提供可靠链接的TCP来讲,在链接超时的状况下必然是先进行重连,若屡次重连仍然无效,则通知应用程序链接超时.

因为HTTP(测试中监听了80端口)是基于TCP协议的,因此对于如下的测试能够反映出TCP的重连表现:

pi@happyPi:~ $ sudo tcpdump -n -i eth0 port 80 &
pi@happyPi:~ $ wget www.google.com
11:30:13.695658 IP 192.168.1.108.37366 > 59.24.3.173.80: Flags [S], seq 1964502452, win 29200, options [mss 1460,sackOK,TS val 13783 ecr 0,nop,wscale 7], length 0
11:30:14.692904 IP 192.168.1.108.37366 > 59.24.3.173.80: Flags [S], seq 1964502452, win 29200, options [mss 1460,sackOK,TS val 13883 ecr 0,nop,wscale 7], length 0
11:30:16.692946 IP 192.168.1.108.37366 > 59.24.3.173.80: Flags [S], seq 1964502452, win 29200, options [mss 1460,sackOK,TS val 14083 ecr 0,nop,wscale 7], length 0
11:30:20.702931 IP 192.168.1.108.37366 > 59.24.3.173.80: Flags [S], seq 1964502452, win 29200, options [mss 1460,sackOK,TS val 14484 ecr 0,nop,wscale 7], length 0
11:30:28.722938 IP 192.168.1.108.37366 > 59.24.3.173.80: Flags [S], seq 1964502452, win 29200, options [mss 1460,sackOK,TS val 15286 ecr 0,nop,wscale 7], length 0
11:30:44.742930 IP 192.168.1.108.37366 > 59.24.3.173.80: Flags [S], seq 1964502452, win 29200, options [mss 1460,sackOK,TS val 16888 ecr 0,nop,wscale 7], length 0
11:31:16.822969 IP 192.168.1.108.37366 > 59.24.3.173.80: Flags [S], seq 1964502452, win 29200, options [mss 1460,sackOK,TS val 20096 ecr 0,nop,wscale 7], length 0
failed: Connection timed out.

能够看到重连的时间间隔为[1,2,4,8,16,32]s,并且重连了6次数.

关于次数,是由"/proc/sys/net/ipv4/tcp_syn_retries"内核变量来决定的.

pi@happyPi:~ $ cat /proc/sys/net/ipv4/tcp_syn_retries 
6

3.4 TCP状态链接

一.客户端的状态

  • 创建链接
右边是状态名称且状态过程是从左到右 SYN_SENT ESTABLISHED
缘由 使用系统调用connect发送一个同步报文段 收到服务器的确认报文段
进一步的操做 回复给服务端确认报文段
  • 关闭链接
右边是状态名称,状态过程是从左到右 FIN_WAIT_1 FIN_WAIT_2 TIME_WAIT
缘由 向服务器发送结束报文段 收到服务器的确认报文段 收到服务器结束报文段
进一步的操做 回复给服务端确认接收报文段
备注 FIN_WAIT_1可直接至TIME_WAIT

二.服务端的状态

  • 创建链接
右边是状态名称,状态过程是从左到右 LISTEN SYN_RCVD ESTABLISHED
缘由 使用系统调用listen监听请求链接 监听到某个请求链接 收到客户端确认报文段
进一步的操做 回复给客户端确认报文段
  • 关闭链接
右边是状态名称,状态过程是从左到右 CLOSE_WAIT LAST_ACK CLOSED
缘由 收到客户端的结束报文段 发送给客户端结束报文段 收到客户端的确认报文段
进一步的操做 回复给客户端确认报文段

由以上的过程能够获得下面几个结论:

  1. 对于TCP的链接创建,通常来说是客户端早于服务端,由于服务端的通讯创建完成还得收到客户端的确认报文段,而此时客户端已经创建完成.

  2. 处于FIN_WAIT_2状态的客户端须要等待服务器发送结束报文段,才能转移至TIME_WAIT,不然将一直停留在这个状态.

  3. 在备注里提过的,FIN_WAIT_1状态能够直接进入TIME_WAIT(不通过FIN_WAIT_2),前提是处于FIN_WAIT_1状态的服务器直接收到带确认信息的结束报文段(而不是先接收确认报文段,再接收结束报文段).

长时间处于FIN_WAIT_2状态的链接称之为孤儿链接,Linux为防止孤儿链接长时间留在内核中,定义了如下两个变量,分别指定内核能接管的孤儿链接数目与其在内核中生存的时间.

pi@happyPi:~ $ cat /proc/sys/net/ipv4/tcp_max_orphans 
4096
pi@happyPi:~ $ cat /proc/sys/net/ipv4/tcp_fin_timeout 
60

三.TIME_WAIT状态

在上面客户端关闭的状态中有一个是TIME_WAIT,即在客户端收到服务器的结束报文段以后,并无直接进入CLOSED状态.

TIME_WAIT有两个缘由:

  • 可靠的终止TCP链接,由于避免回复给服务器的确认报文段发送失败.

  • 保证让迟来的TCP报文段有足够的时间被识别并丢弃.万一关闭此端口后被其余程序使用并收到了原来的数据报.

有时咱们但愿避免TIME_WAIT状态,由于当程序退出后,咱们但愿可以当即重启它.但因为处在TIME_WAIT状态的链接还占用着端口,程序将没法启动(直到MSL(Maximum Segment Life,报文段最大生存时间)超时时间结束,标准文档建议的MSL为2min).

对于客户端程序来讲,一般不用担忧上面描述的重启问题,由于它们通常使用系统自动分配的临时端口号创建链接,因为随机性,通常会与上次(还处于TIME_WAIT状态的端口号)使用的不一样.但若是老是异常终止则说明使用的是一个知名服务端口号.

下图是在Windows上TCP链接的状态:

活动链接

  协议  本地地址          外部地址        状态
[cloudmusic.exe]
  TCP    192.168.1.106:13355    119.44.11.138:http     ESTABLISHED
 [cloudmusic.exe]
  TCP    192.168.1.106:13359    119.44.11.138:http     ESTABLISHED
 [cloudmusic.exe]
  TCP    192.168.1.106:13360    119.44.11.138:http     ESTABLISHED
 [cloudmusic.exe]
  TCP    192.168.1.106:13362    119.44.18.47:http      LAST_ACK
 [cloudmusic.exe]
  TCP    192.168.1.106:13366    119.44.11.138:http     ESTABLISHED
 [cloudmusic.exe]
  TCP    192.168.1.106:13392    tsa01s08-in-f14:https  LAST_ACK
 [firefox.exe]
  TCP    192.168.1.106:13394    ti-in-f138:http        SYN_SENT
 [firefox.exe]
  TCP    192.168.1.106:13395    ti-in-f101:http        SYN_SENT
 [firefox.exe]
  TCP    192.168.1.106:13396    59.111.160.195:http    LAST_ACK
 [cloudmusic.exe]
  TCP    192.168.1.106:13397    119.44.18.47:http      ESTABLISHED
 [cloudmusic.exe]
  TCP    192.168.1.106:13398    ti-in-f138:http        SYN_SENT
 [firefox.exe]
  TCP    192.168.1.106:13399    ti-in-f101:http        SYN_SENT
 [firefox.exe]

能够看到这些状态是能够在系统中明文标注出来的.进以分析出当前某个程序的链接状态.


3.5 复位报文段

产生复位报文段的三种状况:

  1. 访问不存在的端口.

  2. 目标端口仍处于TIME_WAIT状态.

  3. 处理半打开链接.半打开即通讯双方关闭或者异常终止了链接,而未通知对方,并继续向对方发送数据报.

这在第1种状况下抓取到的TCP报文段:

pi@happyPi:~ $ sudo tcpdump -nt -i eth0 port 54321 &
pi@happyPi:~ $ telnet  192.168.1.100 54321
Trying 192.168.1.100...
IP 192.168.1.108.48326 > 192.168.1.100.54321: Flags [S], seq 1285841519, win 29200, options [mss 1460,sackOK,TS val 4294956710 ecr 0,nop,wscale 7], length 0
IP 192.168.1.100.54321 > 192.168.1.108.48326: Flags [R.], seq 0, ack 1285841520, win 0, length 0

可见收到了带Flags[R.]的报文段.


3.6 TCP数据流

本节讨论经过TCP链接交换的应用程序数据,TCP报文段所携带的应用程序数据按照长度分为两种:

  • 交互数据

  • 成块数据

前者对实时性要求高如telnet与ssh等,后者对传输效率要求高如ftp等.

一. TCP交互数据流

这种数据流的传输方式有一个特色,服务器每次发送的确认报文段都包含它须要发送的应用程序数据.服务器的这种处理方式称为延迟确认,即它不立刻确认上次收到的数据,而是在一段延迟时间后查看本端是否还有数据须要发送,如有,则和确认信息一块儿发出,这样作的理由是为了减小发送TCP报文段的数量.

在局域网中交互数据流可能经受很大的延迟,而且,携带交互数据的微小TCP报文段数量通常不少(客户端上一个按键就会致使一个TCP报文段),这些因素均可能致使拥塞发生,解决这个问题的一个简单有效的方法是使用Nagle算法,它会要求一个TCP链接的通讯双方在任意时刻都最多只能发送一个未被确认的TCP报文段.具体的表如今于,发送方在等待确认的同时,收集本端须要发送的微量数据,并在确认信息到来时以一个TCP报文段将他们所有发出,如此一来就极大的减小了网络上微小TCP报文段的数量.表面上看来就是"确认到达的越快,数据就发送的越快".

二. TCP成块数据流

当传输大量大块数据的时候,发送方会连续发送多个TCP报文段(因为文件太大),可是接收方能够一次确认这些全部这些报文段.

并且发送方会根据接收方的报文段中接收通告窗口(Window)的大小了解到接收方的接收缓冲区还有多少空闲空间,而且可能会发送一个带PSH标志的报文段以通知应用程序尽快读取数据.

三.带外(Out Of Band,OOB)数据

带外数据用于通告对方本端发生的重要事件.所以,带外数据比普通数据有更高的优先级,它应该是被当即发送,而不管发送缓冲区是否有排队等待发送的普通数据.而且它可使用一条独立的传输层链接,也能够映射到传输普通数据的链接中.

UDP/TCP没有真正的带外数据,不过TCP利用其头部中的紧急指针标志和紧急指针两个字段,给应用程序提供了一种紧急方式.

TCP接收端只有在接收到紧急指针标志时候才会检查紧急指针,而后根据紧急指针所指的位置肯定带外数据的位置,并将它读入一个特殊的缓存中(这个缓存只有1字节,称为带外缓存).若上层应用没有及时取走带外缓存中的数据,则后续的带外数据将覆盖它.固然,经过设置相关参数,带外数据也能够像普通数据同样被TCP模块存放在TCP接收缓存区.


3.9 TCP超时重传

若在创建正常链接后忽然网络情况异常甚至与服务器直接断开,TCP必须可以重传超时间内未收到确认的TCP报文段,为此,TCP模块为每一个TCP报文段都维护一个重传定时器,该定时器在TCP报文段第一次被发送时启动.若是超时时间内未收到接收方的应答,TCP模块将重传TCP报文段并重置定时器.至于下次重传的超时时间如何选择,以及最多执行多少重传,这就是TCP的重传策略.

在Linux上有两个重要内核参数与TCP重传相关,他们分别是在底层IP接管以前TCP最少执行的重传次数和链接放弃前TCP最多能够执行的重传次数.

pi@happyPi:~ $ cat /proc/sys/net/ipv4/tcp_retries1
3 
pi@happyPi:~ $ cat /proc/sys/net/ipv4/tcp_retries2
15

在TCP重传机制下屡次尝试失败的状况下,将会交给底层的IP和ARP接管,直到所使用的应用程序放弃链接为止.


3.10 拥塞控制

因为TCP模块还有一个重要任务,就是提升网络利用率,下降丢包率,并保证网络资源对每条数据流的公平性,这就是所谓的拥塞机制.

TCP的拥塞机制有四个部分:

  • 慢启动(slow start).

  • 拥塞避免(congestion avoidance).

  • 快速重传(fast retransmit).

  • 快速恢复(fast recovery).

拥塞算法在Linux下有多种实现,好比reno/vegas/cubic算法,在Linux机器上,"/proc/sys/net/ipv4/tcp_congestion_control"中指示了机器当前所使用的拥塞机制控制算法.

pi@happyPi:~ $ cat /proc/sys/net/ipv4/tcp_congestion_control 
cubic

下面介绍在发送数据时起到影响数据发送量的几个术语:

SWND(Send Window,发送窗口) SMSS(Sender Maximum Segment Size,发送者最大段大小) RWND(Receiver Window,接收窗口) CWND(Congestion Window,拥塞窗口)
发送端向网络一次连续写入的数据量 发送者最大段大小,通常等于MSS 接收方可经过其控制发送端的SWND 最终用来控制发送端的SWND,实际值是RWND和CWND的较小者

发送端须要合理的选择SWND的大小,若是SWND过小,会引发明显的网络延迟;反之,若SWND太大,则容易致使网络拥塞.TCP的拥塞机制最重要的任务就是调整CWND的大小,由于它才是最终的SWND.

在TCP链接创建好以后,CWND会被设置为初始值IW(Initial Window),其大小为SMSS的整数倍.
接着为避免拥塞:

  1. CWND += MIN(N,SMSS).(N为这次确认中包含的以前未被确认的字节数)    (3.0)
    当CWND大于ssthresh(slow start threshold size,慢启动门限),进入第2步.

  2. CWND += SMSS * SMSS/CWND.    (3.1)
    使得CWND按照线性方式增加,从而减缓其扩大.

若发生了拥塞,则多是下面两种状况引发的:

  • 传输超时(TCP重传定时器溢出).

  • 接收到重复的确认报文段.

如果前者的状况,则当即重传并经过以下公式的调整,SWND将小于SMSS,也小于ssthresh,同时再次进入慢启动阶段.

ssthresh = max(FlightSize / 2,2 * SMSS),CWND <= SMSS    (3.2)

如果后者的状况,按照收到的确认报文段数量不一样作出相应的反映:

  1. 当收到第3个重复的确认报文段时,就认为网络真的发生拥塞了.按照公式(3.2)计算ssthresh,而后当即重传丢失的报文段,接着设置CWND = ssthresh+3*SMSS.

  2. 每次收到1个重复的确认时,设置CWND += SMSS.

  3. 当收到新数据的确认时,按照公式(3.2)计算ssthresh,接着CWND=ssthresh.

快速重传和快速恢复完成以后,拥塞控制将恢复到拥塞避免阶段,由第三步可得知.

综合以上的可见关键在于根据当前网络的状态调整CWND的大小以提升传输效率.


关于第3章的总结

这一章从四个部分学习了TCP协议:

  1. TCP头部信息.主要是通讯的端口指定,TCP链接的管理,控制通讯双方的数据流.

  2. TCP状态转移过程.主要是通讯双方在链接到关闭整个过程的状态变化.

  3. TCP数据流.主要是交互数据流和成块数据流.

  4. TCP数据流的控制.主要是超时重传和拥塞控制.

这一章知识点比较多,对TCP的总体有了一个总体的了解.它比IP协议具备更强的可操做性.


From

Linux 高性能服务器编程 游双著 机械工业出版社

MarkdownPad2

2017/1/21 0:00:09

相关文章
相关标签/搜索