当前位置:文档之家› TCPIP协议栈的基本工作原理

TCPIP协议栈的基本工作原理

TCP/IP协议栈的基本工作原理 TCP/IP是互联网的核心协议,也是大多数网络应用的核心协议。就前面一段时间面试中问到的TCP/IP问题,这里给出一个简单的小结。

TCP由RFC793、RFC1122、RFC1323、RFC2001、RFC2018以及RFC2581定义。

(1) TCP概述 a. TCP提供的是面向连接的全双工服务。 TCP所有的数据会匹配到由源地址,目的地址,源端口,目的端口构成的一个TCP连接之上。TCP连接是一种需要建立的资源,可以通过之后会讲到的握手机制来完成。UDP是一种基于尽力而为机制的协议,不存在UDP连接资源的建立,资源的处理往往由应用层协议代劳了。

b. TCP是提供的可靠服务。 TCP有确认机制来保证数据包的可靠到达, TCP有CRC校验机制来保证数据包的无差错性,UDP的CRC是可选的, TCP会重新排序乱序的数据包和丢弃重复的数据, TCP能够提供流量控制机制,使用滑动窗口算法, TCP能提供拥塞控制与恢复机制,存在多种TCP拥塞控制模型, TCP能协商发送的数据报文长度。

TCP报头。 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 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ TCP Header Format

对于TCP头的标记位,SYN标记只在三次握手(或四次握手)的时候的被置位,ACK标记会在握手之后所有的TCP报文中被置位。当然也有一些特殊情况,比如有些情况下RST报文不会置位ACK。 这些规则也许在配置复杂的ACL中有用。

(2) TCP协议栈的状态机 (摘自RFC793)

a. TCP连接的建立。TCP连接的建立有主动打开,被动打开以及同时打开三种情况。 三次握手比较清楚,要强调的是ISN,就是初始序列号的选择问题,序列号是32位的,针对不同的OS,初始序列号的选择往往也是有规律的。

TCP传输的最大报文长度也是在三次握手中协商的。具体说是在也仅在SYN报文中协商的。MSS = MTU - ip_header_len - tcp_header_len。MSS这里也是为了防止分片,提高网络带宽利用率。

TCP三次握手中,最后一个报文ACK,不需要再有额外的确认机制,如果这个ACK在网络中丢弃了,TCP协议栈也有其他的机制来处理。 除了三次握手,还有一种很特殊的应用情况,就是TCP两端同时打开的情况(发送syn),这种情况没有描述在上面的状态机中。

举例子来说,A通过源端口7777发起到B的目的端口8888的连接的同时,B也通过源端口8888发起对A的目的端口7777的TCP连接。

b. TCP连接的关闭 TCP连接的关闭也有主动关闭,被动关闭和同时关闭三种情况,这三种情况在上面的TCP状态机中都有描述。 TCP连接的关闭需要报文四次交互,因为TCP是一个全双工的服务,所以每个方向的连接都关闭后,TCP的连接才是完整的拆除。 状态机中,主动关闭和同时关闭最后都会进入到一个TIME_WAITE状态。针对TCP主动关闭的最后一个报文应该是ACK,确认对端的FIN报文。这个状态的概念是该TCP连接的资源并没有完全释放,因为还要确保最后一个ACK报文能够无误的到达对端,确认对端的FIN,否则就仍然要重传ACK。 这个等待的过程(或者资源没有完全释放的过程)需要等待2MSL时间(考虑报文一次往返)。MSL是最大报文生存时间,RFC793中为2分钟,根据不同的TCP实现,一般是30s或者1分钟。

所以在TIME_WAITE状态内,该TCP连接所使用的端口和连接资源,不能被继续使用。但是很多TCP实现并没有这个限制,只要新的TCP连接所使用的ISN大于TIME_WAITE状态TCP连接所使用的最后序号即可。实现中往往使用 new ISN = latest ISN in time_waite + 128000

IP报文的最大生存时间是TTL值,TCP报文的最大生存时间是MSL,二层上没有报文最大生存时间的概念,存在风暴的可能。

(3) TCP的滑动窗和定时器 a. TCP的报文确认机制。 TCP使用的是滑动窗口机制来发送数据流,所以TCP协议允许连续发送多个TCP分组而不等待对端的确认。所以发送的分组数据和确认不是一对一的关系。 TCP中,对数据的确认往往是延迟的,一般情况是两个TCP数据对应一个确认,在时延定时器没有溢出的情况下。如果时延定时器溢出了,那么自然也会发送确认报文。 但是,针对存在交互大量微小报文的TCP应用,过于频繁的确认会导致网络利用率的低效,所以TCP支持一种Nagle算法。

b. 延时定时器 当TCP收到报文时候,启动延时定时器,比如200ms。

c. Nagle算法 TCP连接上只能存在一个未被确认的微小报文(41字节的TCP报文),在该确认到达前,TCP仅仅收集微小报文,当确认到达后,以一个分组的形式发出去。 当然,某些应用需要关闭Nagle算法。

d. 滑动窗口机制 窗口合拢(左移):在收到对端数据后,自己确认了数据的正确性,这些数据会被存储到缓冲区,等待应用程序获取。但这时候因为已经确认了数据的正确性,需要向对方发送确认响应ACK,又因为这些数据还没有被应用进程取走,这时候便需要进行窗口合拢,缓冲区的窗口左边缘向右滑动。注意响应的ACK序号是对方发送数据包的序号,一个对方发送的序号,可能因为窗口张开会被响应(ACK)多次。

窗口张开(右移):窗口收缩后,应用进程一旦从缓冲区中取出数据,TCP的滑动窗口需要进行扩张,这时候窗口的右边缘向右扩张,实际上窗口这是一个环形缓冲区,窗口的右边缘扩张会使用原来被应用进程取走内容的缓冲区。在窗口进行扩张后,需要使用ACK通知对端,这时候ACK的序号依然是上次确认收到包的序号。

窗口收缩,窗口的右边缘向左滑动,称为窗口收缩,Host Requirement RFC强烈建议不要这样做,但TCP必须能够在某一端产生这种情况时进行处理。

e. 重传定时器 目的是为了获得对端的确认报文。如果多次重传仍然没有获得确认,则会发送复位报文RST。

这里我们再来看一下TCP的三次握手。 A(发起端) ---> syn ---> B(服务器) A(发起端) <--- syn/ack <--- B(服务器) A(发起端) ---> ack ? B(服务器) 如果TCP客户端A的最后一个ACK丢失了,TCP服务器B没有收到,会是一种什么情况? 这个时候A已经进入到了Establish状态,然而B还只是Syn_Recev状态,所以服务器会重传syn/ack报文,只到连接的最终建立。但是客户端A已经到建立状态了,所以A是有可能发送TCP数据给服务器B的。 所以TCP的两端,最终状态机是有可能不一致的。

后面会详细讲述重传和拥塞控制机制。

f. 坚持定时器 由于TCP没有对ACK的确认机制,所以当接收端窗口从0恢复到一定值的时候,如果接收端发给发送端的ACK报文(标识窗口大小)丢失了,发送端就永远不知道接收端的窗口恢复情况了。 所以发送端会定时发送带一个字节的ACK给接收端,查看接收端的确认报文中的窗口信息。

g. 保活定时器 由于物理原因,处于IDLE状态的TCP连接一端崩溃的时候,TCP有保活机制来判断对端是否仍然工作。这个设计存在争议,也许应用层应该实现该功能。RFC1122中有描述,保活定时器默认是关闭的。下面截取了一些RFC描述。 Implementors MAY include "keep-alives" in their TCP implementations, although this practice is not universally accepted. If keep-alives are included, the application MUST be able to turn them on or off for each TCP connection, and they MUST default to off.

(4) TCP拥塞控制算法:慢启动、拥塞避免、快速重传和快速恢复 针对拥塞控制,主要有四种模型,即TCP TAHOE,TCP RENO,TCP NEWRENO和TCP SACK。TCP TAHOE模型是最早的TCP协议之一,它由Jacobson提出。

Jacobson观察到,TCP报文段(TCP Segment)丢失有两种原因,其一是报文段损坏,其二是网络阻塞,而当时的网络主要是有线网络,不易出现报文段损坏的情况,网络阻塞为报文段丢失的主要原因。针对这种情况,TCP TAHOE对原有协议进行了性能优化,其特点是,在正常情况下,通过重传计时器是否超时和是否收到重复确认信息(dupack)这两种丢包监测机制来判断是否发生丢包,以启动拥塞控制策略;在拥塞控制的情况下,采用慢速启动(Slow Start)算法和“拥塞避免”(Congestion Avoidance)算法来控制传输速率。 1990年出现的TCP Reno版本增加了“快速重传 ”(Fast Retransmit)、“快速恢复”(Fast Recovery)算法,避免了网络拥塞不严重时采用“慢启动”算法而造成过度减小发送窗口尺寸的现象,这样TCP的拥塞控制就主要由这4个核心算法组成。 a. 超时与重传 RTT的计算与RTO的计算

相关主题