十分钟了解运输层协议结构

本文共计5496字,预计阅读用时约十一分钟。

目录

运输层概述

TCP概述

TCP连接建立:三次握手

第一次握手

第二次握手

第三次握手

TCP连接关闭:四次挥手

第一次挥手

第二次挥手

第三次挥手

第四次握手

TCP可靠数据传输原理

序号

确认号

定时器

冗余确认

校验和

TCP流量控制

TCP拥塞控制

慢启动

拥塞避免与丢包

快速恢复


 

运输层概述

         运输层位于因特网协议栈的的第四层,位于应用层之下网络层之上。运输层最重要的功能是多路复用与多路分解,这是一个运输层协议必须实现的最基本功能。多路复用表示运输层协议从应用层进程获取到应用层报文段后将其封装为运输层报文后定向指定套接字推向网络层的过程,而多路分解表示运输层在接收到报文数据后获取并根据报文内的目的端口号信息将数据导向指定套接字并交付给进程的过程。值得注意的是多路复用时运输层由更高层级的应用层调用,多路分解时则是由低层级的网络层调用。

        通过上面的讲解我们可以发现,网络层与运输层最大的区别就是网络层是端与端之间的协议,而运输层是进程与进程之间的协议。网络层实现在路由器内,而运输层与较高层级的应用层相同是实现于端主机里的。

        一个运输层分组内应该具备四个基本信息,分别是:源IP、源端口、目的IP与目的端口。目的IP和目的端口分别表示数据要发送向的接收端主机和接收端主机里的指定套接字。源IP和源端口表示发送分组的端主机与套接字,如果接收端需要对发送端进行响应,那么就将会根据收到分组内的源IP和源端口进行响应,此时对于接收端来说收到的分组内的源IP和源端口就是目的IP和目的端口。在初步了解运输层后下面来介绍拥有代表性的典型运输层协议TCP。

TCP概述

        TCP作为一个面向连接的运输层协议在电子邮件、文档文件传输等需要多次反复通讯并保证数据正确性、完整性的使用场景得到了广泛的应用。TCP的特征是拥有连接状态、可靠传输、拥有流量与拥塞控制。

        TCP实现了在运输层进行数据分片从而避免了某个分片丢失导致整个IP数据包作废的情况,TCP会测量端到端整个链路上的MTU来配置MSS后对数据进行分片,特别注意MSS只包括应用层数据长度,运输层报文段(含首部)不包括在内,MSS的典型值为1460字节。

TCP连接建立:三次握手

        端与端之间的TCP通讯首先需要建立TCP连接,两个端在建立一个TCP连接状态时需要与指定端口进行三次握手来确保两端都能正常的相互发送或接收数据,并配置变量和缓存连接才能正确建立,下文假定客户端发起连接请求。

第一次握手

        客户端还未发送连接请求时处于CLOSED状态,服务端没有收到连接请求时也处于CLOSED状态持续监听请求。

        第一次握手需要声明一个TCP套接字并发送一个运输层报文对服务端的进程进行连接请求,报文不包含应用层数据,SYN为1并随机指定一个client_isn。第一次握手中客户端发送的连接请求报文称为TCP SYN报文,发送TCP SYN报文后客户端处于SYN_SENT状态等待服务端确认。

第二次握手

        服务端在收到TCP SYN后处于LISTEN状态并对其进行确认,发送一个SYN为1并随机选择server_isn的报文且同样不包含应用层数据。在第二次握手中服务器对TCP SYN进行确认的报文称为SYNACK报文,服务器在发送后处于SYN_RCVD状态。

第三次握手

        客户端在收到SYNACK后处于ESTABLTSHED状态并对其进行确认,发送一个SYN为0确认号为server_isn+1的报文,报文允许包含应用层数据。服务器收到这个报文后也处于ESTABLTSHED状态,连接完成。

TCP连接关闭:四次挥手

        对于一条两端都已经处于ESTABLTSHED状态的TCP连接,可以通过四次挥手确保在此连接中两端互相发送的分组数据都已交付完毕后关闭连接,下文假定客户端发起关闭连接请求。

第一次挥手

        客户端向服务端发送报文请求关闭TCP连接,FIN为1,在发送报文后客户端处于FIN_WAIT_1状态。

第二次挥手

        服务端接收到客户端发来的FIN报文,对此进行确认,FIN为1,在发送报文后服务端处于CLOSE_WAIT状态。客户端接收到服务端发来的确认报文后客户端处于FIN_WAIT_2状态。

第三次挥手

        服务端向客户端发送报文,FIN为1,此时服务器处于LAST_ACK状态等待客户端的确认。

第四次握手

        客户端接收到服务端发来的FIN报文,对其进行确认,此时客户端处于TIME_WAIT状态等待定时器后进入CLOSED状态。

TCP可靠数据传输原理

        TCP实现可靠数据传输的中心思想是当一个分组差错或丢失时,该分组的发送端应该在尽可能短的时间内意识到并重新发送该分组。发送端重新发送差错、丢失分组的行为称为重传。

序号

        在一条TCP连接中为每个TCP报文指定一个唯一序号有诸多益处,比如能够让接收端判断发送端发送的分组是新的分组还是之前发生差错、丢失后重传的分组、以及在后面会讲到的确认分组和冗余分组中接收方判断分组间隙都有着不可或缺的作用。

        前文讲过,TCP连接建立的第一次握手中发起连接的客户端指定过一个client_isn序号,第二次握手中服务端也指定过server_isn序号。在连接建立后此连接中互相交付的TCP报文就是依照握手中的client_isn和server_isn为初始值后以连接中的字节流累加确定某个报文的序号的。

        例如服务端向客户端发送报文,server_isn为981那么此连接中服务端发送的第一个报文序号就为981,此时我们假定服务端发送的第一个报文大小为78个字节,那么第二个报文的序号应为1059,客户端向服务端发送报文也是同理。

确认号

        接收端正确收到分组后对发送端发送ACK报文,表示自己已正确收到某个分组,发送端不必重传该分组。

        ACK报文的确认号字段置为要确认的分组序号加上该分组的字节大小,比如在上文的案例中,接收端正确收到了序号为981的分组后发送ACK,981的大小为78字节,确认号置为1059表示接收端已经正确收到此TCP连接中发送端发送的1058及之前的字节。

定时器

        TCP不存在否定确认,因此定时器是作为TCP最基础的引发重传事件的方式存在的。当一个分组在链路中丢失时接收端不对该分组做确认,因此当发送端在一段时间后还未收到ACK时发送端可以判断该分组或分组的ACK丢失了,这时发送端重传分组。而一段时间具体是多少时间是由定时器的Timeoutlnterval值决定的,在TCP连接建立的第一次握手中创建定时器并配置第一个Timeoutlnterval,根据RFC 6298指出连接中第一个Timeoutlnterval值推荐为1秒。

        第一个在之后的连接中TCP会在任意时间通过往返的分组更新Timeoutlnterval。可以设想到的是Timeoutlnterval不应太长,过长会延迟重传丢失分组。但Timeoutlnterval也不应太短,太短会导致未丢失的不必要重传的分组被重传,因为当一个分组的定时器发生超时重传事件时也许该分组或分组的ACK还在链路中并未到达。

        综上所述Timeoutlnterval应是链路上的往返时间并加上一定富有弹性的余量。在实践中一般无法得到一个绝对典型的往返时间,往返时间会因为端或路由器等原因瞬间大范围的波动,这时测量的往返时间显然是非典型的,TCP需要对单次测量的具体往返时间即SampleRTT进行估计得到一个曲线相对更平缓更典型的往返时间即eq?EstimatedRTT%3D%281%20-%20a%29*EstimatedRTT+a*SampleRTT,根据RFC 6298指出a推荐为0.125。EstimatedRTT是SampleRTT的指数加权移动平均数。在估计出了相对典型的往返时间后,还需要增加富有弹性的余量才能得到合适的Timeoutlnterva值。这个余量大小应该适应SampleRTT与EstimatedRTT的波动,即在时延增大时这个余量也该大点,时延减少时这个余量也该小点,这个余量是eq?DevRTT%3D%281-b%29*DevRTT+b*%28SampleRTT-EstimatedRTT%29,根据RFC 6298指出b推荐为0.25。DevRTT是SampleRTT与EstimatedRTT偏移量的指数加权移动平均数。最后Timeoutlnterval=EstimatedRTT+4*DevRTT。

冗余确认

        为了尽量减小链路时延带来的性能问题,尽可能的利用链路速率,TCP是流水线式的,即发送端在推出一个分组后,在该分组后还未得到接收端的ACK情况下可以立即发送预定的下一个分组。那么接收端大概率会面临一种情况即在对一个分组发送ACK后的没有得到期望的分组,而是得到了一个失序的分组。

        还是上文的那个例子,接收端收到了序号为981的分组后对其ACK,此时接收端的期望分组为1059,但接收端却得到了序号为1227失序分组,那么接收端能够检测到字节流发生间隙,判断一个序号为1059大小为168字节的分组丢失了。发生此类事件后接收端对最后一个正确收到的有序分组进行多次发送ACK,即序号为981的分组,发送端接收到对单个分组超过三次的ACK后立即重传该分组之后的分组。另外接收端可以选择两种对失序分组的处理方法,丢弃失序分组或把失序分组放入TCP接收缓存直到收到缺失分组后使用。

校验和

        校验和是用于接收端分辨接收到的分组是否发生差错的编码方式,属于差错控制编码的一种适合如运输层这样的上层协议使用,除了TCP使用的校验和还有CRC校验等适合底层硬件的差错控制编码,关于CRC校验本文作者推荐阅读CRC校验详解(附代码示例)_crc校验代码-CSDN博客

        校验和由发送端计算接收端验证发送端发送一个报文时把该报文的校验和字段置为0,获取TCP伪首部、数据段的二进制值,然后把它们相加对溢出回卷后进行反码运算,校验和字段置为运算结果。例如我们拥有1010011010101000 1001001010110100对它们进行上述运算即可得到1100011010100010。接收端在接收到一个TCP报文后把该报文的TCP伪首部、报文段的二进制值和校验和相加,运算结果应为1111111111111111,如果运算结果中任何一个bit为0表示校验失败,校验和保护范围内出现了差错,接收方丢弃该报文不做确认。

TCP流量控制

         TCP不允许缓存区溢出,这意味着当一次TCP连接的缓存没有空闲时TCP会丢弃该连接中之后收到的数据。而流量控制就是为了控制发送端的供给载荷和接收端的接收缓存空闲相互适应,即发送端不应该发送超过当时接收端接收缓存空闲大小的数据量。

        接收缓存空闲即接收窗口,在TCP中用变量rwnd表示。接收端使用eq?rwnd%3DRcvBuffer-%28LastByteRcvd-LastByteRead%29计算得到rwnd值,变量LastByteRead表示接收端进程获取到的最后一个字节编号,变量LastByteRcvd表示接收缓存从网络层获取到的最后一个字节的编号。然后用缓存容量RcvBuffer减去它们的差,即缓存中数据的字节大小即可得到接收窗口rwnd。接收端通过把rwnd值放入TCP报文的接收窗口字段来向发送端指出自己的缓存空闲容量。

        发送端可以通过获取LastByteSent和LastByteAcked这两个变量的差得到发送端发送后暂未得到ACK的数据量,发送端需要保证未得到ACK的数据量小于接收端的rwnd,这样发送端就能减少发送接收端不能接收的数据了。

TCP拥塞控制

        网络拥塞是指过大的数据量占用资源带宽导致链路、路由堵塞,分组数据滞留在链路中或在路由队列中堆积,高时延和高丢包率是拥塞的体现,这时如果不加以控制而是继续发送大量数据会导致本可以避免的拥塞越来越严重造成奔溃。当一个越来越大的路由队列会造成越来越大的排队时延,最终导致路由缓存不足以支撑过长的队列时路由缓存溢出发生丢包。

        在其他运输层协议中往往会采用GBN协议或SR协议的方式对流水线式的供给载荷进行控制,从而尽可能解决网络拥塞,而TCP提供了更合适的拥塞控制方式即TCP拥塞控制。TCP拥塞控制是通过控制端的供给载荷与拥塞程度相匹配,在避免拥塞的基础上尽可能利用信道性能的算法,由RFC 2581与RFC 5681定义。

        与流量控制类似,拥塞控制通过改变拥塞窗口控制供给载荷,拥塞窗口表示为变量cwnd。发送端的供给载荷不应大于cwnd,所以未确认数据大小必须小于等于rwnd和cwnd的最小值。

慢启动

        连接建立时TCP拥塞控制首先处于慢启动状态,在慢启动状态开始时cwnd为一个MSS,后每一个传输轮次快速的以指数翻倍增长。一个传输轮次是指发送一个cwnd大小的分组为为一个轮次,本轮次的分组全部得到ACK后本传输轮次结束进入下一个轮次。

        例如第一个传输轮次的cwnd为1MSS,那么当第一个传输轮次一MSS的数据都得到ACK时进入第二个轮次。第二个传输轮次的cwnd为2MSS,第三个传输轮次为4MSS。

拥塞避免与丢包

        当慢启动状态的cwnd增长到初始ssthresh值16MSS后进入拥塞避免状态,在拥塞避免状态cwnd以每一传输轮次就增加1MSS的方式小幅度线性增长。发生以超时指示的丢包事件时cwnd降为1MSS并重新进入慢启动状态,更新ssthresh值为cwnd\2。

        例如发送端检测到一个分组的超时这指示了一个丢包,于是进入慢启动状态,丢包发生在cwnd增长到28MSS时,那么新的ssthresh值为14这意味着当之后慢启动状态的cwnd增长到14后进入拥塞避免状态。

快速恢复

        发生以冗余ACK指示的丢包事件时会进行快速恢复,更新ssthresh值并将cwnd降为降为新的ssthresh值后进入拥塞避免状态。

        例如发送端在cwnd为22MSS收到冗余ACK,执行快速恢复把cwnd减少至11进入拥塞避免状态每一传输轮次以加法增大。

        

        

        

        

  • 20
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值