海南省建设网站首页,网站美化怎么做,美化wordpress h2,wordpress插件 数据本章目录4. TCP连接4.1 TCP报文段的首部格式4.2 TCP连接如何保证可靠4.3 ARQ协议4.3.1 停止等待ARQ协议4.3.1.1 无差错情况4.3.1.2 出现差错情况4.3.1.3 确认丢失和确认迟到4.3.2 连续ARQ协议4.3.2.1 流水线传输4.3.2.2 累积确认4.3.2.3 滑动窗口协议4.3.3 停止等待ARQ和连续AR…
本章目录4. TCP连接4.1 TCP报文段的首部格式4.2 TCP连接如何保证可靠4.3 ARQ协议4.3.1 停止等待ARQ协议4.3.1.1 无差错情况4.3.1.2 出现差错情况4.3.1.3 确认丢失和确认迟到4.3.2 连续ARQ协议4.3.2.1 流水线传输4.3.2.2 累积确认4.3.2.3 滑动窗口协议4.3.3 停止等待ARQ和连续ARQ的对比4.3.4 ARQ到底运行在那一层4.4 三次握手4.4.1 三次握手的步骤4.4.2 三次握手的作用4.4.3 为什么需要最后一次握手4.4.4 如果已经建立了连接但是客户端突然故障了怎么办4.4.5 三次握手时报文的初始化序号ISN是固定的吗4.4.6 什么是半连接队列4.4.7 三次握手过程中可以携带数据吗4.5 四次挥手4.5.1 四次挥手的步骤4.5.2 为什么最后客户端要等待2*MSL4.6 为什么建立连接是三次握手而释放连接是四次挥手4.7 流量控制4.7.1 什么是流量控制4.7.2 如何实现流量控制4.7.3 如何避免流量控制引发的死锁4.8 拥塞控制4.8.1 什么是拥塞控制4.8.2 为什么需要拥塞控制4.8.3 如何知道网络的拥塞情况4.8.4 到达瓶颈值了怎么办4.8.5 超时一定是网络拥塞吗4.9 拥塞控制和流量控制的区别4. TCP连接
4.1 TCP报文段的首部格式
传输层的TCP协议会将应用层交付下来的报文加上TCP首部TCP首部有20字节的固定开销以及有长度可变的部分。 源端口和目的端口各占2个字节序号和确认号各占4个字节。
序号seq序号seq用来表示从TCP发送方向接收方发送的字节流的起始序号 TCP连接中传送的字节流中的每个字节都按顺序编号。例如一段报文的序号seq301携带的数据长度为100字节那么下一个报文段的数据序号应该从401开始。 确认号ack确认号ack是接收方期望收到发送方下一个报文段的第一个数据字节的序号。只有当ACK1时确认序号字段才有效。 例如S收到了C发送过来的seq501的报文而数据长度为200字节这表明S应该正确收到了C发送过来的序号在[501,700]的数据。因此S期望收到的C发送来的下一个数据序号为701于是S在发送给C的确认报文段中把确认号置为701. 数据偏移占4位它指出TCP报文的数据距离TCP报文段的起始处有多远。窗口占2个字节用来通知接收方本报文需要有多大的空间来接收。
标识位
确认标识ACK用来标识数据包的成功接收。仅当ACK为1的时候确认才有效。复位标识RST当RST1表明TCP连接中出现严重差错必须释放连接然后再重新建立连接同步标识SYN建立连接时用来同步序号。当SYN1ACK0时表明这是一个连接请求报文当SYN1ACK1时表示这是一个同意请求报文终止标识FINFIN用来释放连接。当FIN1时表示此段报文发送方已发送完毕。
4.2 TCP连接如何保证可靠
校 序 重 流 拥 校验和 TCP会保持它的首部和数据的校验和这是一个端到端的检验和目的是检测数据在传输过程中的任何变化。如果发现校验和有差错就会丢弃接此报文段不对这个报文段进行确认。 确认应答和序列号 TCP传输时将每个字节的数据都进行了编号这就是序列号。发送端按序发送报文接收端按序收到报文后会给发送端一个ACK确认报文并且该报文中带有ack表示下一次发送端应该从哪个地方开始发送报文。 超时重传 发送端每发出一个报文段就启动一个定时器。如果发送端发送的报文段一定时间内没有收到ACK确认就会重新发送该报文段。如果接收端已经有了该报文段就会丢弃刚刚发送过来的报文段。 超时重传保证报文即使丢失也能再传输直到成功传输为止从而保证可靠。 流量控制 发送端如果数据发送过快导致接收端的缓冲区很快就满了如果持续下去数据溢出缓冲区就会出现数据丢失。这时需要在发送端和接收端有一个窗口窗口的作用为在发送缓冲区只有在窗口里面的数据才能被发送在接收缓冲区只有在窗口里的数据才能被接收接收端收到数据之后会回复ack发送端会根据ack的值来判断接收能力从而动态调整窗口大小实现流量控制。 拥塞控制 如果网络出现拥塞TCP会根据不同情况采用不同的算法慢开始拥塞避免快重传快恢复来对窗口大小cwnd和慢开始门限值ssthresh进行调整从而降低网络拥塞的可能性。
4.3 ARQ协议
TCP保证可靠传输的确认应答和超时重传机制是靠ARQ协议实现的ARQ协议 ARQAutomatic Repeat Quest自动重传请求是OSI模型中的错误纠正协议之一。 ARQ协议通过确认和重传这两个机制在不可靠的基础上实现可靠的信息传输。 如果发送方在发送后的一段时间内没有收到确认帧他通常会重新发送。 重传的请求是自动进行的接收方不需要请求发送方重传某个出错的分组。
4.3.1 停止等待ARQ协议
“停止等待”就是每发送完一个分组就停止发送等待对方的确认。在收到确认后再发送下一个分组。
停止等待协议ARQ的优缺点 4.3.1.1 无差错情况 4.3.1.2 出现差错情况
如果出现差错会有两种差错情况
B接收M1时检测出了差错于是B就丢弃M1其他什么也不做不通知发送方AM1在传输过程中丢失了这时B什么也不知道更什么也不做
这两种差错情况下接收方B什么也不做。发送方A超过一段时间仍然没有收到确认就认为刚刚的分组丢失了就会重传之前这个未被确认的分组。这就是超时重传。 4.3.1.3 确认丢失和确认迟到
Note确认是名词指的是接收方给发送方发的ACK确认不是动词-确定
如果出现了差错发送方A进行了超时重传那么接收方B假定收到了这个重传的分组M1。这时接收方B应该采取两个行动
如果之前已经收到过分组M1那么就会丢弃这个重复的分组M1不向上交付否则收下M1向A发送确认
如果传输过程中没有出现差错但是接收方B对分组M1的确认迟到了。那么由于超时重传发送方A会收到重复的确认对于收到的重复的确认发送方直接丢弃。 发送方A和接收方B是如何知道重复的从而需要丢弃呢——编号
发送方A为每一个发送的分组都进行编号。如果接收方B收到的重复编号的分组就会将其丢弃并回送确认。接收方B对发送的确认也进行编号指示该确认是对哪一个分组的确认。
4.3.2 连续ARQ协议
4.3.2.1 流水线传输
为了提高传输效率发送方可以不采用低效率的停止等待协议而是采用流水线传输即发送方可以连续发送多个分组不必每发送完一个分组就停顿下来等待对方的确认这样可以使信道上一直有数据不间断地传送。 流水线传输通常要求
必须增加序号范围。因为每个传输的分组必须有一个唯一的序号可能存在有多个在传输中未确认的报文。发送方和接收方要能缓存多个分组发送方至少要能缓存那些已发送但是没有被确认的分组接收方要能缓存那些已正确接收到的分组。解决流水线传输的差错有两种滑动窗口协议回退NGo-back-N和选择重传SR。
当使用流水线传输时要使用连续ARQ协议和滑动窗口协议。
4.3.2.2 累积确认
累积确认接收方不必对收到的分组逐个发送确认而是对按序到达的最后一个分组发送确认这就表示“到这个分组为止的所有分组都已经正确收到了”。
但同时累积确认也有缺陷例如发送方传送了5个包但是第3个包丢失了第4和第5个正常。这时根据累积确认接收方只能传送前两个包的ACK按序到达的最后一个。在接收到第2个包ACK的发送方不知道后面3个包是否到达就会将后3个包全部进行重传即Go-back-N。
累积确认的优缺点
优点容易实现即使ACK确认丢失也不必重传指的是接收方不必重传缺点不能向发送方反映出接收方已经正确收到的所有分组的信息如上面的例子只有中间的数据包丢失后面的可能也被正确接收
4.3.2.3 滑动窗口协议
滑动窗口协议以基于分组的数据传输协议为特征因此该协议适用于对按顺序传输分组可靠性要求较高的环境。
提供TCP的可靠性最基本的传输可靠性来源于“确认重传”机制避免丢包提供TCP的流控特性用于网络数据传输时的流量控制以避免拥塞的发生。滑动窗口协议在发送方和接收方之间各自维持着一个滑动窗口发送窗口和接收窗口两个窗口大小不一定相同使用滑动窗口协议控制发送方和接收方所能发送和接收的分组的数量和编号它允许发送方发送多个分组而不需要等待确认TCP的滑动窗口是以字节为单位的每收到一个确认发送方就把发送窗口向前滑动
4.3.3 停止等待ARQ和连续ARQ的对比 4.3.4 ARQ到底运行在那一层 ARQ是一种可以在不可靠的数据通道上可靠地传输数据的方案所以其实链路层和传输层都用了ARQ并不专属某一层。 并不是一条连接只要有一层用了ARQ它的上层的通信就是可靠的。因为ARQ只保证使用它的点到点是可靠的比如数据链路层只保证你和你的路由器通信可靠你的路由器到小区的路由器通信也可靠 但是路由器本身会故障会拥塞丢包也就是点本身会产生问题。 所以需要在传输层或者应用层再加一层ARQ保障整条数据通道的可靠性。比如你自己写程序要在应用层通信但传输层不用TCP想用UDP也可以在你程序里用ARQ协来实现可靠性。
4.4 三次握手
TCP 三次握手其实就是 TCP 应用在发送数据前通过 TCP 协议跟通信对方协商好连接信息建立起TCP的连接关系。
TCP连接并非是在通信设备两端之间建立信号通道而是双方各自维护所需的状态已达到TCP连接的效果。 4.4.1 三次握手的步骤
初始最初客户端和服务器都是处于CLOSED关闭状态。服务器进程创建传输控制块TCB被动打开进入LISTEN监听状态时刻准备接收客户端的连接请求。第一次握手客户端进程创建传输控制块TCB然后客户端给服务器发送一个连接请求报文指明同步位SYN1且客户端的初始化序列号ISNInitial Sequence Numberseqx。此时客户端处于SYN-SENT同步已发送状态。SYN报文段不能携带数据但是需要消耗掉一个序号。第二次握手服务器收到客户端的连接请求报文后如果同意连接则会向客户端发送确认报文。ACK1SYN1并且也指定了自己的初始化序列号ISNseqy同时ackx1由于连接请求报文seqx不携带数据但消耗一个序号所以ackx1表示自己已经收到了客户端的SYN报文。此时服务器处于SYN_RCVD同步已收到状态。确认报文也不能携带数据也是仍然消耗一个序号。第三次握手客户端收到确认报文后还要向服务器发出确认。确认报文的ACK1seqy1自己的序列号为seqx1。此时客户端进入ESTABLISHED已建立连接状态。当服务器收到客户端的确认后也进入ESTABLISHED已建立连接状态。此时双方就可以进行数据传输了。
4.4.2 三次握手的作用
确认收发双方的发送、接收能力是否都正常 第一次握手客户端发服务器收这样服务器能够得出结论客户端的发送能力、服务器的接收能力正常。第二次握手服务器发客户端收这样客户端能够得出结论客户端的发送、接收能力与服务器的发送、接收能力是正常的。所以第二次握手后客户端就进入ESTABLISHED状态。第三次握手此时服务器还不知道客户端的接收能力和服务器的发送能力是否正常。所以才有了第三次握手。客户端发服务器收这样服务器得出结论客户端的发送、接收和服务器的发送、接收能力都是正常的。所以第三次握手后服务器才进入ESTABLISHEDh状态。 指定自己的初始化序列号为后面的可靠传送做准备
4.4.3 为什么需要最后一次握手
确认客户端和服务器双方的发送、接收能力是否均正常。如果只采用两次握手服务器无法判断客户端的接收能力和服务器的发送能力是否正常确认序列号的可靠同步。如果是两次握手服务端无法确定客户端是否接收到了自己发送的初始序列号。如果第二次握手报文丢失客户端无法知道服务端的初始序列号那么TCP连接的可靠性无法保证。阻止重复历史连接的初始化。客户端由于某种原因发送了两个不同序号的SYN报文由于复杂的网络环境有可能旧的SYN先到达服务器。采用三次握手客户端在收到服务器发送的确认报文后对比ack是对应旧的SYN报文还是新的SYN报文如果是对应旧的那么客户端就给服务器发送RST报文直到正常的SYN到达服务器后才正常建立连接。阻止超时请求建立连接浪费资源。如果一个连接请求在网络中传输的比较慢超时后客户端会重新发送该连接请求但是最后之前那个慢的连接请求最后还是到达了服务器。如果只采用两次握手的话就会建立两个TCP连接浪费资源。如果采用的是三次握手就算是那之前失效的连接请求传送过来了服务端接受到了那条失效请求并且回复了确认报文但是客户端不会再次发出确认。由于服务器收不到确认就知道客户端并没有请求连接。
4.4.4 如果已经建立了连接但是客户端突然故障了怎么办
TCP连接有一个保活计时器。服务器每收到一次客户端的请求后都会重新复位这个计时器通常时间设置为2小时。如果2小时内服务器一直未收到客户端的任何数据服务器就会向客户端发送一个探测报文段并且每隔75秒发送一次。如果一连10个探测报文都没有反应服务器就认为客户端出现故障接着就会关闭连接。
4.4.5 三次握手时报文的初始化序号ISN是固定的吗
三次握手的一个重要功能是客户端和服务器交换ISN以便让对方知道接下来接收数据的时候如何按序列号组装数据。
如果ISN是固定的攻击者很容易就能猜出来后续的确认号因此为了避免被攻击者猜到从而发送伪造的 RST报文因此ISN是动态生成的。
4.4.6 什么是半连接队列
服务器第一次疏导客户端的连接请求后就会从LISTEN状态进入SYN-RCVD状态此时双方还没有完全建立连接。服务器会把这种状态下的请求连接放在一个队列里这就是半连接队列。
当然还有全连接队列就是已经完成三次握手的连接。
如果队列满了就可能会出现丢包的现象。
关于SYN-ACK重传次数的问题服务器发送完SYN-ACK报文如果未收到客户端的确认报文服务器进行首次重传等待一段时间仍未收到客户确认包进行第二次重传。如果重传次数超过系统规定的最大重传次数系统将该连接信息从半连接队列中删除。注意每次重传等待的时间不一定相同一般会是指数增长例如间隔时间为 1s, 2s, 4s, 8s, ….
4.4.7 三次握手过程中可以携带数据吗
第一次、第二次握手不可以携带数据而第三次握手是可以携带数据的。
我们可以思考一个问题假如第一次握手可以携带数据的话如果有人要恶意攻击服务器那他每次都在第一次握手中的 SYN 报文中放入大量的数据疯狂着重复发 SYN 报文这会让服务器花费大量的内存空间来缓存这些报文这样服务器就更容易被攻击了。
对于第三次握手此时客户端已经处于连接状态他已经知道服务器的接收、发送能力是正常的了所以可以携带数据是情理之中。
4.5 四次挥手 4.5.1 四次挥手的步骤
起初客户端和服务器都是处于ESTABLISHED状态。如果数据传输完毕要释放连接客户端主动关闭服务器被动关闭。客户端进程发出连接释放报文并且停止发送数据。释放报文首部FIN1序列号sequ。此时客户端进入FIN-WAIT-1终止等待1状态。FIN报文即使不携带数据也要消耗一个序号。服务器收到连接释放报文后发出确认报文。ACK1acku1并且带上自己的序号seqv。此时服务器进入CLOSE-WAIT关闭等待状态。这时客户端向服务器方向的连接就释放了处于半关闭状态即客户端没有数据要发送了但是服务器若发送数据客户端依然接受。这个CLOSE-WAIT状态要持续一段时间用于服务器把未发完的数据发送给客户端。客户端收到服务器的确认请求后客户端进入FIN-WAIT-2终止等待2状态等待服务器发送连接释放报文。在这之前还需要接收服务器发送的最后的数据服务器将最后的数据发送完毕后就向客户端发送连接释放报文FIN1ACK1acku1并带上自己的序号seqw在半关闭状态时服务器可能又发送了数据所以序号由u变为w。此时服务器就进入LAST-ACK最后确认状态等待客户端的确认。客户端收到服务器的连接释放报文后必须发出确认ACK1ackw1而自己的序号是sequ1。此时客户端进入了TIME-WAIT时间等待状态。此时TCP连接还没有释放必须经过2*MSL2倍的最长报文段寿命的时间后当客户端撤销相应的TCB后才进入CLOSED状态。服务器只要收到了客户端发出的确认立即进入CLOSED状态并撤销TCB。可以看到服务器结束TCP连接的时间要比客户端早一些。
4.5.2 为什么最后客户端要等待2*MSL
保证客户端发送的最后一个ACK报文能够达到服务器。因为这个ACK报文有可能丢失站在服务器的角度我已经发送了FINACK的释放报文但是客户端没有给出确认那我就认为是客户端没有收到我发送的释放报文于是我就重新发送一次这个释放报文。这样客户端就能在这个2MSL客户端ACK到达服务器 服务器发送 FIN重传包一来一回时间内收到这个重传的报文并给出确认并且重启2MSL计时器。如果等待 2MSL 时间也没有收到服务器端的重传包 FIN说明可以确认服务器已经收到客户端发送的 ACK。防止类似于三次握手中提到的“已经失效的连接请求报文出现在本连接中”。客户端在发送完最后一个ACK报文后的2MSL时间内就可以使本连接持续的时间内所产生的所有报文都从网络中消失使得下一个新的连接中就不会出现旧连接的请求报文。即避免本次连接中的请求进入下一次连接场景路由器缓存IP数据包。
4.6 为什么建立连接是三次握手而释放连接是四次挥手
建立连接的时候服务器在LISTEN状态下收到建立连接请求的SYN报文后把ACK和SYN放在一个报文里发送给客户端。
释放连接的时候服务器收到客户端的FIN报文时仅仅表示客户端不再发送数据了但是客户端还可以接收数据而自己也可能还有数据没有全部传送过去所以服务器可以选择把所有数据全部发送给客户端之后再关闭连接因此这时仅仅给客户端发送一个ACK报文表示自己已经收到了客户端发来的连接释放请求但是还不能立即同意释放连接。所以当服务器把数据全部发送完毕后给客户端发送FIN报文表示同意现在关闭连接。
从上面可以看出建立连接的时候服务器把ACK和SYN报文放在一起发送给了客户端表示同意建立连接。而在释放连接的时候服务器先发送一个ACK报文告诉客户端已经收到了释放连接的请求但是自己还未发完全部数据所以暂时还不同意释放连接等到数据全部发送完毕服务器再发送一个FIN报文告诉客户端同意释放连接。确认和同意释放连接报文分开发送是四次挥手的原因。
4.7 流量控制
4.7.1 什么是流量控制
简单来说流量控制就是让发送方的发送速率不要太快要让接收方来得及接收。本质就是防止分组丢失。
接收端会维护一个处理窗口就是接收端所能处理数据的能力。接收端将这个处理能力不断反馈给发送端以此来让发送端调整发送的数据量的多少。
总结来说对发送方发送速率的控制我们称之为“流量控制”。
4.7.2 如何实现流量控制
由滑动窗口协议连续ARQ协议实现。该协议既保证了分组无差错、有序接收也实现了流量控制。
主要的方式为接收方返回给发送方的ACK报文中会包含自己的接收窗口大小rwnd发送方利用接收窗口大小控制自己的发送窗口。
4.7.3 如何避免流量控制引发的死锁
死锁的发生场景
接收方B给发送方A发送了rwnd0的报文段后发送方就知道不再向接收方发送数据了。不久后如果B的接收缓存又有了一些空间于是B向A重新发送一个含有非零rwnd的报文。然而这个报文段在传输过程中丢失了。发送方A一直在等待非零rwnd的报文接收方B也一直在等待A发来的数据。如果没有其他措施这种互相等待的死锁局面将一直持续下去。
如何解决死锁
为了解决上述问题TCP为每一个连接设有一个持续计时器。只要发送方A收到了接收方B的零窗口rwnd报文后就启动持续计时器。如果持续计时器的时间到期发送方A就发送一个零窗口探测报文段仅携带1个字节的数据接收方B收到后就在确认这个探测报文段时给出现在的接收窗口值rwnd。如果rwnd仍然是0那么发送方就重置这个持续计时器。如果rwnd不是0那么就可以打破死锁僵局。
4.8 拥塞控制
4.8.1 什么是拥塞控制
拥塞控制就是防止过多的数据注入到网络中这样可以使网络中的路由器或者链路不至于过载。
4.8.2 为什么需要拥塞控制
当网络拥堵的时候发送方的数据包可能一直未到达接收端那么发送端误认为出现了丢包情况于是就重传这个数据包结果就造成了不仅浪费了信道资源还使得网络更加拥塞。因此需要进行拥塞控制。
4.8.3 如何知道网络的拥塞情况
A与B建立连接之后A就可以向B发送数据了。然而这个时候A并不知道此时的网络拥塞情况如何也就是说A不知道一次性连续发送多少个数据包好我们也把A一次性连续发送多少个数据包称之为拥塞窗口用N代表此时拥塞窗口的大小。
如果线性增大拥塞窗口的大小速率太慢了如果指数增大拥塞窗口的大小可能很快就到达瓶颈值了。所以采用“前期指数增长到达阈值ssthresh后线性增长”的策略。注意这个阈值ssthresh并不是出现网络拥塞时的瓶颈值
把前期指数增长阶段称之为“慢启动”到达阈值后的线性增长阶段称之为“拥塞避免”。 这里的指数增长是因为每个传输轮次中发送方每收到一个对新报文段的确认就使拥塞窗口1这样实现了相邻轮次间拥塞窗口的加倍增长。
传输轮次就是往返时间RTT但RTT不是固定不变的。例如拥塞窗口的大小为4个报文段那么这时的往返时间RTT就是发送方连续发送4个报文段并收到这4个报文段的确认总共经历的时间。
4.8.4 到达瓶颈值了怎么办
在慢启动和拥塞避免过程中最终肯定会出现超时这时就认为网络出现拥塞了把此拥塞窗口的瓶颈值用MAX表示那么拥塞窗口就不能再继续增长了并且需要进行缩小调整。
策略出现网络拥塞时拥塞窗口大小回到最初的状态1将阈值ssthreshMAX/2继续进行慢启动和后续的拥塞避免。
4.8.5 超时一定是网络拥塞吗
超时是指发送方在指定时间内没有收到对数据包的确认可能是出现了网络拥塞也可能是因为某个数据包丢失或者损坏了一直未收到对该数据包的确认从而导致这个数据包的超时事件发生了。
为了防止这种情况我们通过冗余ACK来处理的。
数据包是有序号的如果A给B发送M1, M2, M3, M4, M5…N个数据包如果B收到了M1, M2, M4…却始终没有收到M3这个时候就会重复确认M2最后一个连续数据包的序号称为“快重传”意在告诉A M3还没收到可能是丢失了。 当A连续收到了三个对M2的ACK且M3的超时事件还没有发生。A就知道M3可能丢失了这时A就不必等待M3设置的计时器到期而是快速重传M3。并把阈值ssthreshMAX/2注意MAX是出现超时的时候的拥塞窗口瓶颈值可能是拥塞也可能是丢包所以只要出现超时时的拥塞窗口值就是MAX它并不是固定不变的而是根据具体超时情况改变的。但是这时并非把拥塞窗口N设置为1而是让Nssthresh并以拥塞避免的方式线性增长增大拥塞窗口。这种情况称之为“快恢复”。 4.9 拥塞控制和流量控制的区别
拥塞控制是作用于网络的它是防止过多的数据注入到网络中避免出现网络负载过大的情况。流量控制是作用于接受者的它是控制发送方的发送速率从而使接收方来得及接收防止分组丢失。拥塞控制与网络的拥堵情况相关联而流量控制与接收方的缓存状态相关联。拥塞控制是一个全局性的过程涉及到所有的主机、路由器以及与降低网络传输性能有关的所有因素。流量控制是点对点通信量的控制是一个端到端的问题接收端控制发送端。