TCP
Posted 程石亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP相关的知识,希望对你有一定的参考价值。
TCP提供一种面向连接的,可靠的字节流服务。
在TCP连接中,仅有两方进行彼此通信。
TCP提供可靠的运输层。它使用的方法之一就是确认从另一端收到的数据。但数据和确认都有可能会丢失。TCP通过在发送时设置一个定时器来解决这种问题。如果当定时器溢出时还没有收到确认,它就重传该数据。
TCP通过下列方式提供可靠性:
应用数据被分割成TCP认为最合适发送的数据块,由TCP传递给IP的信息单位称为报文段
当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段,如果不能及时收到一个确认,重发该报文段
当TCP收到发自TCP连接另一端的数据,他将推迟几分之一秒发送一个确认
TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据在传输过程的任何变化,如果收到的检验和有差错,TCP将丢弃该报文段和不确认收到此报文段(不希望发送端超时重发)
TCP将对收到的数据重新排序,将收到的数据以正确的顺序交给应用层
TCP接收端必须丢弃重复的数据报(IP数据报会发生重复)
TCP提供流控制,TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许另一端发送接收端缓冲区所能接收的数据,这将防止较快主机致使较慢的缓冲区溢出
TCP首部:20字节长
源端口号(16bit)+目的端口号(16bit)+序号(32bit)+确认序号(32bit)+首部长度(4bit)+保留(6bit)+URG+ACK+PSH+RST+SYN+FIN+窗口大小(16bit)+检验和(16bit)+紧急指针(16bit)
源端口号和目的端口号加上IP首部中的源IP地址和目的IP地址确认一个TCP连接
一个IP地址和一个端口号称为一个插口,即插口对可确认一个TCP连接
序号用来标识从TCP发送端向TCP接收端发送的数据字节流,对每个字节进行计数
一个新的连接建立时,SYN置为1
确认序号包含发送确认的一端期望的下一个序号,是上次已成功接收到的数据字节序号加1,只有ACK置为1是确认序号才有效
URG 紧急指针
ACK 确认序号有效
PSH 接收方应该尽快将这个报文段交给应用层
RST 重建连接
SYN 同步序号用来发起一个连接
FIN 发送端完成发送任务
窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。
检验和覆盖了整个TCP报文段(包含首部),由发送端计算和存储,由接收端进行验证。也是用伪首部
只有URG置为1时紧急指针才有效,紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据的最后一个字节。许多实现不正确地称 T C P 的紧急方式为带外数据 。有些实现是将紧急指针设置为紧急数据最后字节的下一个字节。
TCP选项
最常见的选项字段是最长报文大小,称为MSS.只能出现在SYN报文段中,如果一方不接收来自另一方的MSS值,则MSS默认值是536字节,可以将MSS值设为外出接口上的MTU长度减去IP首部和TCP首部。如果目的IP和本地IP的子网号不一样,那么MSS得值默认为536字节
选项表结束: kind = 0 (1字节)
无操作: kind = 1 (1字节)
最大报文段长度: kind = 2 len = 4 最大报文段长度 (1+1+2字节)
窗口扩大因子: kind = 3 len = 3 移位数 (1+1+1字节)
时间戳: kind = 8 len = 10 时间戳值 时间戳回显应答 (1+1+4+4字节)
其中len指选项部分总长度
在建立连接的阶段,如果定时器到没有连上,则会重新发送SYN连接。一般在75s后放弃连接
2MSL等待状态:
TIME_WAIT状态也称为2MSL等待状态。是报文段被丢弃前在网络内的最长时间。
当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN).这样可以让TCP再次发送最后的ACK以防这个ACK丢失(另一端并重发最后的FIN).同时定义这个连接的插口只能在2MSL时间后才能再使用
FIN_WAIT_2状态
在FIN_WAIT_2状态已经发出了FIN,并且另一端已经返回了ACK。当完成另一端的半关闭时,从FIN_WAIT_2进入到FIN_WAIT状态,此时可能该端可能永远处于FIN_WAIT_2状态,解决办法就是启动一个计时器,让TCP进入CLOSE_WAIT状态。
复位报文段RST
一个报文段发往基准连接出现错误,TCP都会发出一个复位报文段。分为以下情况:
到一个不存在的端口的连接请求,会返回复位报文段
使用复位报文段来异常终止一个连接
如果一端异常关闭,并未断开存在的连接,造成半打开连接状态,这一端重启程序后如果另一端继续发数据,则回复复位报文段
经受时延的确认
在收到数据时,TCP连接被标记为产生一个经受时延的确认,在开始启用的固定时间的定时器中,该定时器在相对于内核引出的固定时间溢出。定时到,则会发送一个ACK确认,这叫做经受时延的确认。 如果定时器溢出之前,有数据要发送到另一端,则把数据一起发送,ACK时延顺延下一个定时器溢出时间。
Nagle算法
该算法要求一个TCP连接上最只能有一个为被确认的未完成的小分组,在该分组的确认到达前不能发送其他的小分组,TCP收集这些少量的分组,并在确认到来前以一个分组的形式发出去。该算法是自适应的,确认到达的越快,数据也就发送的越快。
滑动窗口
窗口大小是与确认序号相对应的。发送方计算它的可用窗口,该窗口表明多少数据可以立即接收。
窗口左边沿向右边沿靠近为窗口合拢。这种现象发生在数据接收和确认时。
窗口右边沿向右移动将允许发送更多的数据,称之为窗口张开。这种现象发生在接收进程读取已经确认的数据并释放了TCP的接收缓存时。
窗口右边沿向左移动时,称之为窗口收缩。
窗口左边沿受发送的确认序号控制,不会向左移动
慢启动、拥塞、吞吐量
慢启动为发送方的TCP增加另一个窗口:拥塞窗口,cwnd。当建立TCP连接时,拥塞窗口初始化为一个报文段(即另一端通告的报文段大小MSS)。每收到一个ACK,拥塞窗口就增加一个报文段。发送方取拥塞窗口和通告窗口最小值作为发送上限。
拥塞避免算法
该算法假定由于分组受到损坏引起的丢失是非常少的,因此分组丢失就意味着源主机和目的主机之间的某处网络发生了拥塞.有两种分组丢失的指示:发生超时和接收到重复的确认.当拥塞发生时,可降低分组进入网络的传输速率,于是可以调用慢启动来实现.这种算法需要维持两个变量:一个拥塞窗口cwnd和一个慢启动门限ssthresh.该算法的工作过程如下:
对一个给定连接,初始化cwnd为一个报文段,ssttresh为66535个字节
TCP的输出不能超过cwnd和通告窗口的最小值
拥塞发生时,ssthresh设置为cwnd和通告窗口的最小值的一半,但最小为2个报文段,如果拥塞是由于超时引起的,cwnd为1个报文段
如果数据被确认,就增加cwnd,增加方法依赖是在慢启动或者拥塞避免.如果cwnd小于ssttresh,则为慢启动,否则为拥塞避免.慢启动一直持续到拥塞发生时所处位置一半为止,然后转为拥塞避免.慢启动算法初始化cwnd为一个报文段,收到一个确认,cwnd呈指数增长.拥塞避免算法每次收到一个确认cwnd都会按照1/cwnd速率增加.
超时和重传
RTT:连接的往返时间
RTO:重传超时时间
对于一个数据不能到达对端的连接,发出去的数据会进行重传,首次出现重传发生在数据发出去1s后没有收到响应,以后时间呈2的倍数增长,直至64s,才放弃重传,并发送RST标志位断开连接。这个倍乘关系称为指数退避。Karn算法:当超时和重传发生时,在重传数据的确认最后到达之前,不能更新RTT估计器,数据重传发生,已得到一个RTO值,指数退避就使用该RTO值进行重传。
快速重传算法
TCP对收到的重复ACK进行技术,当收到第3个时,就假定一个报文段已经丢失并重传自那个序号起的一个报文段。此时接收端保存发送端发送的数据,但返回的ACK序号仍然是期望的序号,并不是接收到的数据的序号。当缺少的报文段到达时,将缓存中保存的数据一起提交应用程序,并返回所有接收数据的最大序号为确认序号。
TCP的坚持定时器
ACK的传输不可靠,TCP不对ACK报文段进行确认,只对那些含有数据的ACK确认.基于此,如果一个确认丢失了,发送方在等待允许它继续发送数据的窗口更新,接收方在等待接收数据,这样的情况下,可能会发生死锁.为防止这种情况,发送方使用一个坚持定时器周期性查询(发送一个字节的数据)接收方的窗口更新,这些从发送方发出的报文段称为窗口探查.该定时器触发时间使用指数退避的方式增加间隔:1.5,3,6,12,24,48,60.坚持定时器定时时长在5--60s之间.
糊涂窗口综合症状
发送方可以发送一个满长度的报文段,可以发生那个至少是接收方通告窗口大小一半的报文段
接收方不通告比当前窗口大的窗口,可以通告一个报文段大小的窗口,可以通告接收缓存一半大小的窗口
如果通告了一个1553字节的窗口大小(1553大于1024一个报文段),在发送端发送1024字节后,接收端的缓存大小为529,在这时候529字节也是要通告发送端的.(根据窗口的移动规则,右边沿不能向左移动.)
保活定时器
发送端未断开连接而异常关闭,会造成半开放的连接.如果发送端永远不发送数据(发送数据会收到接收端的复位连接RST),则接收端会永远等待下去,保活定时器就是在接收端检测这种半开放的连接,每隔75s发送一个探查报文,检查发送端的连接状态
如果发送端正常运行,则保活定时器在2H后复位.
如果发送端崩溃已重启,接收端会收到对其探查报文的复位连接的响应,接收端终止这个连接
发送端不响应这个探查报文(有可能已崩溃),则接收端每隔75s发送一个探查报文,如果10个探查报文都没有响应,接收端默认发送端关闭了该连接
ICMP差错的处理
对于源抑制差错报文,会将拥塞窗口cwnd被设置为1个报文段大小来发起慢启动,慢启动门限ssttresh不变,窗口将打开直至它或者开放了所有的通道,或者发生了拥塞
对于主机不可达和网络不可达被忽略掉,连接不关闭,TCP试图重传引起该差错的数据,最后超时引起另一个ICMP差错
以上是关于TCP的主要内容,如果未能解决你的问题,请参考以下文章