
TCP(传输控制协定)
TCP(Transmission Control Protocol 传输控制协定)是一种面向连线的、可靠的、基于位元组流的传输层通信协定,由IETF的RFC 793定义。在简化的计算机网路OSI模型中,它完成第四层传输层所指定的功能,用户数据报协定(UDP)是同一层内另一个重要的传输协定。在网际网路协定族(Internet protocol suite)中,TCP层是位于IP层之上,套用层之下的中间层。不同主机的套用层之间经常需要可靠的、像管道一样的连线,但是IP层不提供这样的流机制,而是提供不可靠的包交换。
套用层向TCP层传送用于网间传输的、用8位位元组表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连线的网路的数据链路层的最大传输单元(MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网路将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果传送端实体在合理的往返时延(RTT)内未收到确认,那幺对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函式来检验数据是否有错误;在传送和接收时都要计算校验和。
基本介绍
- 软体名称:传输控制协定
- 英文名:Transmission Control Protocol
- 简称:TCP
- 行业标準:IETF RFC 793
- 套用範围:Internet
网路协定
功能
当套用层向TCP层传送用于网间传输的、用8位位元组表示的数据流,TCP则把数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受该计算机连线的网路的数据链路层的最大传送单元(MTU)限制。之后TCP把数据包传给IP层,由它来通过网路将包传送给接收端实体的TCP层。
TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的位元组发回一个相应的确认(ACK);如果传送端实体在合理的往返时延(RTT)内未收到确认,那幺对应的数据(假设丢失了)将会被重传。
- 在数据正确性与合法性上,TCP用一个校验和函式来检验数据是否有错误,在传送和接收时都要计算校验和;同时可以使用md5认证对数据进行加密。
- 在保证可靠性上,採用逾时重传和捎带确认机制。
- 在流量控制上,採用滑动视窗协定,协定中规定,对于视窗内未经确认的分组需要重传。
在拥塞控制上,採用广受好评的TCP拥塞控制算法(也称AIMD算法)。该算法主要包括三个主要部分:1)加性增、乘性减;2)慢启动;3)对逾时事件做出反应。
实行标準
TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协定/网间协定,是一个工业标準的协定集,它是为广域网(WAN)设计的。它是由ARPANET网的研究机构发展起来的。
TCP/IP的标準在一系列称为RFC的文档中公布。文档由技术专家、特别工作组、或RFC编辑修订。公布一个文档时,该文档被赋予一个RFC编号,如RFC959(FTP的说明文档)、RFC793(TCP的说明文档)、RFC791(IP的说明文档)等。最初的RFC一直保留而从来不会被更新,如果修改了该文档,则该文档又以一个新号码公布。因此,重要的是要确认你拥有了关于某个专题的最新RFC文档。通常在RFC的开头部分,有相关RFC的更新(update)、排错(errata)、作废(obsolete)信息,提示读者信息的时效性。
首部格式
TCP的首部格式图右图所示:
---Source Port是源连线埠,16位。
TCP首部

---Destination Port是目的连线埠,16位。
---Sequence Number是传送数据包中的第一个位元组的序列号,32位。
---Acknowledgment Number是确认序列号,32位。
---Data Offset是数据偏移,4位,该栏位的值是TCP首部(包括选项)长度除以4。
---标誌位: 6位,URG表示Urgent Pointer栏位有意义:
ACK表示Acknowledgment Number栏位有意义
PSH表示Push功能,RST表示复位TCP连线
SYN表示SYN报文(在建立TCP连线的时候使用)
FIN表示没有数据需要传送了(在关闭TCP连线的时候使用)
Window表示接收缓冲区的空闲空间,16位,用来告诉TCP连线对端自己能够接收的最大数据长度。
---Checksum是校验和,16位。
---Urgent Pointers是紧急指针,16位,只有URG标誌位被设定时该栏位才有意义,表示紧急数据相对序列号(Sequence Number栏位的值)的偏移。
连线建立
TCP是网际网路中的传输层协定,使用三次握手协定建立连线。当主动方发出SYN连线请求后,等待对方回答SYN+ACK,并最终对对方的 SYN 执行 ACK 确认。这种建立连线的方法可以防止产生错误的连线,TCP使用的流量控制协定是可变大小的滑动视窗协定。
TCP的三次握手

TCP三次握手的过程如下:
- 客户端传送SYN(SEQ=x)报文给伺服器端,进入SYN_SEND状态。
- 伺服器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。
- 客户端收到伺服器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。
三次握手完成,TCP客户端和伺服器端成功地建立连线,可以开始传输数据了。
连线终止
建立一个连线需要三次握手,而终止一个连线要经过四次握手,这是由TCP的半关闭(half-close)造成的。具体过程如下图所示。
TCP连线的终止

(1) 某个套用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是传送一个FIN分节,表示数据传送完毕。
(2) 接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。
注意:FIN的接收也作为一个档案结束符(end-of-file)传递给接收端套用进程,放在已排队等候该套用进程接收的任何其他数据之后,因为,FIN的接收意味着接收端套用进程在相应连线上再无额外数据可接收。
(3) 一段时间后,接收到这个档案结束符的套用进程将调用close关闭它的套接字。这导致它的TCP也传送一个FIN。
(4) 接收这个最终FIN的原传送端TCP(即执行主动关闭的那一端)确认这个FIN。
既然每个方向都需要一个FIN和一个ACK,因此通常需要4个分节。
注意:
(1) “通常”是指,某些情况下,步骤1的FIN随数据一起传送,另外,步骤2和步骤3传送的分节都出自执行被动关闭那一端,有可能被合併成一个分节。
(2) 在步骤2与步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的,这称为“半关闭”(half-close)。
(3) 当一个Unix进程无论自愿地(调用exit或从main函式返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连线上也发出一个FIN。
无论是客户还是伺服器,任何一端都可以执行主动关闭。通常情况是,客户执行主动关闭,但是某些协定,例如,HTTP/1.0却由伺服器执行主动关闭。
可靠性实现
可靠性
TCP提供一种面向连线的、可靠的位元组流服务。面向连线意味着两个使用TCP的套用(通常是一个客户和一个伺服器)在彼此交换数据包之前必须先建立一个TCP连线。这一过程与打电话很相似,先拨号振铃,等待对方摘机说“餵”,然后才说明是谁。在一个TCP连线中,仅有两方进行彼此通信。广播和多播不能用于TCP。
TCP通过下列方式来提供可靠性:
1.套用数据被分割成TCP认为最适合传送的数据块。这和UDP完全不同,应用程式产生的数据长度将保持不变。由TCP传递给IP的信息单位称为报文段或段(segment)。
2.当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。当TCP收到发自TCP连线另一端的数据,它将传送一个确认。TCP有延迟确认的功能,在此功能没有打开,则是立即确认。功能打开,则由定时器触发确认时间点。
3.TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段(希望发端逾时并重发)。
4.既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给套用层。
5.既然IP数据报会发生重複,TCP的接收端必须丢弃重複的数据。
6.TCP还能提供流量控制。TCP连线的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端传送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。
两个应用程式通过TCP连线交换8bit位元组构成的位元组流。TCP不在位元组流中插入记录标识符。我们将这称为位元组流服务(bytestreamservice)。如果一方的应用程式先传10位元组,又传20位元组,再传50位元组,连线的另一方将无法了解发方每次传送了多少位元组。只要自己的接收快取没有塞满,TCP 接收方将有多少就收多少。一端将位元组流放到TCP连线上,同样的位元组流将出现在TCP连线的另一端。
另外,TCP对位元组流的内容不作任何解释。TCP不知道传输的数据位元组流是二进制数据,还是ASCⅡ字元、EBCDIC字元或者其他类型数据。对位元组流的解释由TCP连线双方的套用层解释。
这种对位元组流的处理方式与Unix作业系统对档案的处理方式很相似。Unix的核心对一个套用读或写的内容不作任何解释,而是交给应用程式处理。对Unix的核心来说,它无法区分一个二进制档案与一个文本档案。
重传策略
TCP协定用于控制数据段是否需要重传的依据是设立重发定时器。在传送一个数据段的同时启动一个重传,如果在重传逾时前收到确认(Acknowlegement)就关闭该重传,如果重传逾时前没有收到确认,则重传该数据段。在选择重发时间的过程中,TCP必须具有自适应性。它需要根据网际网路当时的通信情况,给出合适的重发时间。
这种重传策略的关键是对定时器初值的设定。採用较多的算法是Jacobson于1988年提出的一种不断调整逾时时间间隔的动态算法。其工作原理是:对每条连线TCP都保持一个变数RTT(Round Trip Time),用于存放当前到目的端往返所需要时间最接近的估计值。当传送一个数据段时,同时启动连线的定时器,如果在定时器逾时前确认到达,则记录所需要的时间(M),并修正RTT的值,如果定时器逾时前没有收到确认,则将RTT的值增加1倍。通过测量一系列的RTT(往返时间)值,TCP协定可以估算数据包重发前需要等待的时间。在估计该连线所需的当前延迟时通常利用一些统计学的原理和算法(如Karn算法),从而得到TCP重发之前需要等待的时间值。
视窗确认
TCP的一项功能就是确保每个数据段都能到达目的地。位于目的主机的TCP服务对接受到的数据进行确认,并向源应用程式传送确认信息。
TCP的状态机

使用数据报头序列号以及确认号来确认已收到包含在数据段的相关的数据位元组。
TCP在发回源设备的数据段中使用确认号,指示接收设备期待接收的下一位元组。这个过程称为期待确认。
源主机在收到确认讯息之前可以传输的数据的大小称为视窗大小。用于管理丢失数据和流量控制。这些变化如右图所示。
配置TCP
修改建立TCP连线的逾时时间
建立TCP连线需要经过三次握手:主动端先传送SYN报文,被动放回应SYN+ACK报文,然后主动端再回应ACK。
l在主动端传送SYN后,如果被动端一直不回应SYN+ACK报文,主动端会不断的重传SYN报文直到超过一定的重传次数或逾时时间。
l在主动端传送SYN后,被动端回应SYN+ACK报文,但主动端不再回复ACK,被动端也会一直重传直到超过一定的重传次数或逾时时间。(SYN报文攻击会出现这种情况)
可以通过以下命令配置SYN报文的逾时时间(传送SYN报文到三次握手成功的最大时间),也就是建立TCP连线的逾时时间。
命令 | 作用 |
R(config)#ip tcp syntime-out seconds | 修改建立TCP连线的逾时时间。 单位秒,取值範围5-300,预设值20 |
使用no ip tcp syntime-out命令恢复参数预设值。
修改缓冲区大小
TCP的接收缓冲区是用来快取从对端接收到的数据,这些数据后续会被应用程式读取。一般情况下,TCP报文的视窗值反映接收缓冲区的空闲空间的大小。对于频宽比较大、有大批量数据的连线,增大接收缓冲区的大小可以显着提供TCP传输性能。TCP的传送缓冲区是用来快取应用程式的数据,传送缓冲区的每个位元组都有序列号,被应答确认的序列号对应的数据会从传送缓冲区删除掉。增大传送缓冲区可以提高TCP跟应用程式的互动能力,也因此会提高性能。但是增大接收和传送缓冲区会导致TCP占用比较多的记忆体。
命令 | 作用 |
R (config)#ip tcp window-size size | 修改TCP连线的接收和传送缓冲区大小。 单位位元组,取值範围0-65535,预设值4096。 |
使用no ip tcp window-size命令恢复接收和传送缓冲区大小为预设值。
禁止连线埠不可达时的重置报文
TCP模组在分发TCP报文时,如果找不到该报文所属的TCP连线会主动回复一个reset报文以终止对端的TCP连线。攻击者可能利用大量的连线埠不可达的TCP报文对设备进行攻击。
可以使用以下命令禁止/恢复在收到连线埠不可达的TCP报文时传送reset报文。
命令 | 作用 |
R (config)#ip tcp not-send-rst | 禁止在接收到连线埠不可达的TCP报文时传送reset报文。 |
使用no ip tcp not-send-rst命令恢复传送reset报文。
限制TCP连线的MSS的最大值
MSS是最大传输段大小的缩写,指一个TCP报文的数据载荷的最大长度,不包括TCP选项。
在TCP建立连线的三次握手中,有一种很重要的工作那就是进行MSS协商。连线的双方都在SYN报文中增加MSS选项,其选项值表示本端最大能接收的段大小,即对端最大能传送的段大小。连线的双方取本端传送的MSS值和接收对端的MSS值的较小者作为本连线最大传输段大小。
传送SYN报文时的MSS选项值的计算方法如下。
l非直连网路中:mss = 默认值536。
l直连网路中:mss = 对端ip地址对应的出口的MTU - 20位元组ip头 - 20位元组tcp头。
一般来说如果出口配置的某些套用影响了接口的mtu,那幺该套用会相应的设定mtu,如隧道口,vpn口等。
一般来说如果出口配置的某些套用影响了接口的mtu,那幺该套用会相应的设定mtu,如隧道口,vpn口等。
到这里得到的rmss值就是要传送的syn报文mss选项的值。举例:一般情况下在直连网路中建立bgp邻居,那幺该连线的传送的mss为1500 – 20 – 20 – 20 = 1440。
ip tcp mss命令的作用是限制即将建立的TCP连线的MSS的最大值。任何新建立的连线协商的MSS值不能超过配置的值。
命令 | 作用 |
R (config)#ip tcp mss max-segment-size | 限制TCP连线的MSS的最大值。 单位为位元组,取值範围68-10000。 |
使用no ip tcp mss命令取消此限制。
启用PMTU发现功能
TCP的路径最大传输单元(PMTU)发现功能是按RFC1191实现的,这个功能可以提高网路频宽的利用率。当用户使用TCP来批量传输大块数据时,该功能可以使传输性能得到明显提升。
命令 | 作用 |
R(config)#ip tcp path-mtu-discovery [ age-timer minutes| age-timer infinite ] | 启用PMTU发现功能。 age-timer minutes:TCP在发现PMTU后,重新进行探测的时间间隔。单位分钟,取值範围10-30。预设值10。 age-timer infinite:TCP在发现PMTU后,不重新探测。 |
按RFC1191的描述,TCP在发现PMTU后,隔一段时间可以使用更大的MSS来探测新的PMTU。这个时间间隔就是使用参数age-timer来指定。当设备发现的PMTU比TCP连线两端协商出来的MSS小时,设备就会按上述配置时间间隔,去尝试发现更大的PMTU。直到PMTU达到MSS的值,或者用户停止这个定时器,这个探测过程才会停止。停止这个定时器,使用age-timer infinite参数。
使用no ip tcp path-mtu-discovery命令关闭PMTU发现功能。
设定接口收发SYN报文的MSS选项值
当客户端发起一个TCP连线时,它通过TCP SYN报文中的MSS选项栏位协商TCP报文数据载荷的最大值,客户端SYN报文的MSS值表示后续伺服器端传送TCP报文数据载荷的最大值,反之同理。

如右图的拓扑,PC用http访问伺服器可能会出现无法访问的情况。因为PC与伺服器端建立的连线MSS协商的都会是1460,但1460的MSS无法通过R1和R2,R1和R2用隧道相连,MTU小于1500。
这时可以通过在R2的(1)口和(2)口上配置如下命令,修改SYN报文中的MSS选项值。从而修改经过(1)口和(2)口的TCP连线协商的MSS值。
命令 | 作用 |
R (config-if)# ip tcp adjust-mssmax-segment-size | 设定接口收发SYN报文的MSS选项值。 单位为位元组,取值範围500-1460。 |
使用no ip tcp adjust-mss命令取消此项设定,则接口收发SYN报文时,不会修改报文的MSS选项值。
在接口上配置本命令会使得该接口接收或传送SYN报文的MSS选项都被改为接口上配置的MSS值。建议出口和入口配置相同的值。如果SYN报文的入口和出口配置了不同的MSS值,经过该设备后,SYN报文的MSS选项被改为这两个口配置值的较小者。
转载请注明出处海之美文 » TCP(传输控制协定)