传输层——TCP

简介

TCP是在不可靠的IP层之上实现的可靠的数据传输协议,它主要解决传输的可靠、有序、无丢失和不重复等问题。
主要特点如下:

  • TCP是面向连接的传输层协议

  • 每条TCP连接只能又两个端点,即点对点(一对一)

  • 提供可靠的交付服务,保证数据的可靠、有序、无丢失和不重复

  • TCP提供全双工通信,允许通信双方的应用进程在任何时候都能接受数据,为此TCP在连接的两端都设有发送缓存和接收缓存。
    发送缓存:①发送应用程序传递给发送方TCP准备发送的数据;②TCP以发送但还没有收到确认的数据。
    接收缓存:①按序接收但还没有被接收程序读取的数据;②不按序到达的程序。

  • TCP是面向字节流的。如果发送了4个有效载荷为512B的报文段,接收方收到后,向应用层 提供2048B的字节流,而不是4个报文段。这是因为TCP是真正的端到端通 信,接收端无需再转发

TCP报文段

整个TCP报文段作为IP数据报的数据部分
在这里插入图片描述

TCP报文段的首部的固定部分大小为20B,首部最小为20B。
后面大小通常为4B的整数倍。
在这里插入图片描述

  1. 源/目的端口号:各占16位,表示发送方和接收方的端口号。

  2. 顺序号:TCP传送的数据流的每一个字节都有一个序号。这个字段指的是本报文段发送的数据的第一个字节的序号。
    例如,一报文段序号为301,携带数据为100B,则它的最后一个字节的序号为400。那么,下个报文段的序号就应该是401.

  3. 确认号:期望对方的下一个报文段的数据的第1个字节的序号。若确认好为N,则表明前N-1个数据已正确接收。

  4. 数据偏移:即首部长度。指出TCP报文段的数据起始处距离TCP报文段的起始处有多远

  5. 保留字段:保留日后使用,置为0

  6. URG:紧急数据标志。当有紧急数据时,该标志为“1”

  7. ACK:该标志若为“1”,则表示确认号有效;若为“0”,则确认号无效。TCP规定,在连接建立后所传输的报文段ACK必须为1

  8. PSH:PSH= 1时,表示要求马上发送数据,不必等到缓冲区满时才发送

  9. RST:该标志用于对本次TCP连接进行复位。通常在TCP连接发生故障时设置本位,以便双方重新同步,并初始化某些连接变量。如接收方收到 它不希望接收的报文段,则将RST置“1 “。

  10. SYN:用于建立TCP连接。 SYN置为“1”且ACK置为“0”,表示请求建立TCP连接 ; SYN置为“1”且ACK置为“1”,表示确认TCP连接

  11. FIN:用于释放连接。若FIN置为“1”,则表示发送方的数据已发送完毕,并要求释放传输连接

  12. 窗口大小:16位,用于TCP流量控制。表示从确认的字节号开始还可以接收多少字节。窗口大小也允许为“0”,表示确认号以前的字 节已收到,但暂停接收数据

  13. 校验和: 16位,用于对TCP报文段进行校验(类似于IP校验和),但校验 范围包括头部和数据部分。计算校验和需包括一个12B的TCP伪头(和UDP一样),这 样有助于检测分组是否被错误递交

  14. 紧急指针:当URG为“1”时,紧急指针给出TCP段中紧急数据的长度, 单位为字节。

  15. 选项:目前TCP只规定一种选项,即最大的TCP段长(MSS),缺省值是 556B。TCP实体双方可通过协商确定一个特定的最大TCP段长。 若MSS选的太小,则由于帧头和报头开销而网络利用率会降低;若MSS 选的太大,则由于IP层分段而增加额外开销。一般认为, MSS应尽可能选 大些,只要IP层不需要分段就行。

  16. 填充:以0为填充位,确保TCP首部长度为4B的整数倍。

  17. 数据:TCP载荷数据,由于IP分组长度限制(IP分组最大65535B,IP头部最大60B,一般20B),TCP最大载荷长度=65535B - 20B - 20B=65495B。

TCP连接管理

TCP连接的端点不是主机,不是主机的IP地址,不是应用进程,也不是传输层的协议端口。TCP连接的端口称为套接字(socket)。
TCP连接的建立采用客户机/服务器方式。主动发起连接建立的应用进程称为客户机,被动等待连接建立的应用程序称为服务器。

建立连接(三次握手)

在这里插入图片描述

客户端发出连接请求TCP段(SYN=1,ACK=0,顺序号=x,其中x为随机整数),指明想要连接的服务器端口号(目的端口),设置TCP段的 最大段长及其它参数。(连接请求报文不携带数据,但消耗一个序号)


服务器的TCP实体收到该请求后,检查是否有进程在监听目的端口,(响应请求报文不携带数据,但消耗一个序号):

  • 如果没有,则返回拒绝TCP段(RST=1)的作为应),拒绝请求。
  • 如果有,则该进程可以接受或拒绝连接请求:
    如果接受,则返回确认TCP段(SYN=1,ACK=1,顺序号=y,确认 号=x+1,其中y为随机整数)。
    如果拒绝则返回拒绝TCP段(RST=1)。


客户端收到确认TCP段后,也发送一个确认TCP段(SYN=0,ACK=1), 并允许该TCP段直接开始发送数据。

问:为什么初始顺序号x必须是随机数而不能为固定值?

  • 如果TCP每次连接都使用固定ISN,黑客可以很方便模拟任何IP与server建立连接
  • 很可能在新连接建立后,上次连接通信的报文才到达,这种情况有概率发生老报文的seq号正好是server希望收到的新连接的报文seq。这就全乱了

RFC1948中提出了一个较好的初始化序列号ISN随机生成算法:
M是一个计时器,这个计时器每隔4毫秒加1。直到超过2^32,又从0开始。一个ISN的周期大约是4.55个小时,只要TCP报文段的最大存活时间小于4.55小时,那么,我们就不会重用到ISN。
F是一个Hash算法,根据源IP、目的IP、源端口、目的端口生成一个随机数值

ISN = M + F(localhost, localport, remotehost, remoteport)

问:为什么不采用“两次握手”建立连接?
是为了防止两次握手情况下己失效的连接请求报文段突然又传送到服务器而产生错 误。考虑下面这种情况。客户A向服务器B发出TCP连接请求,第一个连接请求报文在网络的 某个结点长时间滞留,A超时后认为报文丢失,于是再重传一次连接请求,B收到后建立连接。 数据传输完毕后双方断开连接。而此时,前一个滞留在网络中的连接请求到达服务器B,而B认 为A又发来连接请求,此时若使用“三次握手”,则B向A返回确认报文段,由于是一个失效的 请求,因此A不予理睬,建立连接失败。若采用的是“两次握手”,则这种情况下B认为传输连 接已经建立.并一直等待A传输数据,而A此时并无连接请求,因此不予理睬,这样就造成了B 的资源白白浪费。

注意
服务器端的资源是在第二次握手时分配的,客户端的资源是在第三次握手时分配的(缓存和变量),这也解释了第三次握手的必要性。

释放连接(四次挥手)

在这里插入图片描述

客户端发送连接释放报文段,并停止发送数据。这里的顺序号不再是随机的了,它等于前面已传送的数据的最后一个字节的序号加1

服务器收到连接释放报文段后发出确认。此时,从客户机到服务器这个方向上的连接就释放了,TCP处于半关闭状态。若服务器发送数据,客户机仍要接收,即从服务器到客户机这个方向上的连接未释放。

若服务器没有要向客户机发送的数据了,就通知TCP释放连接

客户机收到释放连接报文段后,发出确认。此时TCP连接还未释放,必须经过时间,等待计时器设置的时间未2MSL(Maximum Segment Lifetime TCP的最大存活时间)后,才真正把连接释放。

问:为何不采用“三次握手释放连接,且发送最后一次握手报文后要等待2MSL的时间呢?
原因有两个:

  • 保证A发送的最后一个确认报文段能够到达B。如果A不等待2M,若A返回的最后 确认报文段丢失,则B不能进入正常关闭状态,而A此时已经关闭,也不可能再重传。

  • 防止出现“已失效的连接请求报文段”。A在发送最后一个确认报文段后,再经过2MSL 可保证本连接持续的时间内所产生的所有报文段从网络中消失。

TCP可靠传输机制

序号

保证能有序提交给应用层.TCP把数据视为一个无结构但有序的字节流,序号建立在传送的字节流上,而不是报文段上

确认

确认号是期望收到对方的下一个报文段的数据的第一个字节的序号.发送方缓冲区会继续存储那些已发送但未收到确认的报文段,以便在需要时重传. TCP默认使用类及确认,即TCP只确认数据流中第一个丢失字节为止的字节.

重传
  • 超时重传
    TCP每发送一个报文段,就对这个报文段设置一个计时器.计时器设置的重传时间到期了都还没有收到确认时,就要重传这个报文段.超时计时器设置的超时时间应该略大于RTTs(加权平均往返时间),但也不能太多,否则保温丢失时,TCP不能很快重传,造成数据传输延迟大.

  • 冗余ACK
    冗余ACK就是再次确认某个报文段的ACK,而发送方之前已经收到过该报文段的确认. TCP规定,每当比期望序号大的失序报文段到达时,就发送一个冗余报文段,指明下一个期待字节的序号. 当发送方收到对同一个报文段的3个冗余ACK时,就可以认定跟在这个被确认的报文段之后的报文段已经丢失.----这种技术通常认为是快速重传,还被用在拥塞控制中.

TCP流量控制

TCP提供流量控制服务来消除发送方时接收方缓存区溢出的可能性,因此可以说梁柳控制是一个速度匹配服务,即匹配发送方的发送速率和接收方的读取速率。
在通信过程中,接收方根据自己接收缓存的大小,动态的调整发送方的发送窗口大小,这称为接收窗口rwnd,即报文段首部中的窗口大小字段。同时,发送方还会根据网络拥塞程序估计而确定的窗口值称为拥塞窗口cwnd。发送方的发送窗口的实际大小取rwnd和cwnd的最小值。
滑动窗口协议来流量控制。

TCP拥塞控制

所谓拥塞控制,是指防止过多的数据注入网络,保证网络中的路由器获链路不致过载。

慢启动和拥塞避免

慢启动:指数增大
设: ssthresh为慢启动阈值,MSS为最大TCP段长度,cwnd为拥塞窗口大小。
发送端初始cwnd一般设置为1个MSS,ssthresh设置为接收窗口大小。
每收到一个确认ACK,则cwnd = cwnd + 1个MSS
初始cwnd=1,发送端发送1个报文段M0 ,接收端收到后返回ACK1 。发送端 收到ACK1后,将cwnd从1增大到2,于是接着发送M1和M2两个报文段。接收端 收到后返回ACK2和ACK3 。发送端收到后,将cwnd从2增大到4,于是接着发送 M3 ~ M6共4个报文段。
当cwnd >ssthresh时,进入拥塞避免阶段。

拥塞避免:加法增大
每经过一个往返传输时间RTT(不管在RTT 时间内收到几个ACK ),则cwnd = cwnd +1个MSS;RTT是动态变化的。
如果超过一段时间(TCP重传超时)没有收到TCP报文段,则认为网络拥塞。

网络拥塞:乘法减小
不管是慢启动阶段,还是拥塞避免阶段,如果TCP检测到拥塞,则将ssthresh缩 减成cwnd的一半,且cwnd恢复为初始大小,即1个MSS。

在这里插入图片描述

快重传与快恢复

快重传和快恢复算法是对慢启动和拥塞避免算法的改进。

快重传:
原理就是前面介绍的冗余ACK:当发送方连续收到3个重复的报文段时,直接重传对方未收到的报文段,而不必等待那个报文段设置的重传计时器超时。

快恢复:
发送端连续接收到3个冗余ACK时,执行乘法减小,但与之前的算法不一样的是:
他把cwnd的值设为慢启动门限ssthresh改变后的数值,而不是设为1
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值