计算机网络笔记、面试八股(四)—— TCP连接

2023-11-07

本章目录

4. TCP连接

4.1 TCP报文段的首部格式

传输层的TCP协议会将应用层交付下来的报文加上TCP首部,TCP首部有20字节的固定开销,以及有长度可变的部分。

源端口和目的端口各占2个字节,序号和确认号各占4个字节。

  • 序号seq:序号seq用来表示从TCP发送方向接收方发送的字节流的起始序号
    • TCP连接中传送的字节流中的每个字节都按顺序编号
    • 例如一段报文的序号seq=301,携带的数据长度为100字节,那么下一个报文段的数据序号应该从401开始。
  • 确认号ack:==确认号ack是接收方期望收到发送方下一个报文段的第一个数据字节的序号。==只有当ACK=1时,确认序号字段才有效。
    • 例如,S收到了C发送过来的seq=501的报文,而数据长度为200字节,这表明S应该正确收到了C发送过来的序号在[501,700]的数据。因此,S期望收到的C发送来的下一个数据序号为701,于是S在发送给C的确认报文段中把确认号置为701.
  • 数据偏移:占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远。
  • 窗口:占2个字节,用来通知接收方,本报文需要有多大的空间来接收。

标识位:

  • 确认标识ACK:用来标识数据包的成功接收。仅当ACK为1的时候,确认才有效。
  • 复位标识RST:当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接;
  • 同步标识SYN:建立连接时用来同步序号。当SYN=1,ACK=0时,表明这是一个连接请求报文;当SYN=1,ACK=1时,表示这是一个同意请求报文
  • 终止标识FIN:FIN用来释放连接。当FIN=1时,表示此段报文发送方已发送完毕。

4.2 TCP连接如何保证可靠

校 序 重 流 拥

  1. 校验和

    TCP会保持它的首部和数据的校验和,这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果发现校验和有差错,就会丢弃接此报文段,不对这个报文段进行确认。

  2. 确认应答和序列号

    TCP传输时将每个字节的数据都进行了编号,这就是序列号。发送端按序发送报文,接收端按序收到报文后会给发送端一个ACK确认报文,并且该报文中带有ack,表示下一次发送端应该从哪个地方开始发送报文。

  3. 超时重传

    发送端每发出一个报文段,就启动一个定时器。如果发送端发送的报文段一定时间内没有收到ACK确认,就会重新发送该报文段。如果接收端已经有了该报文段,就会丢弃刚刚发送过来的报文段。

    超时重传保证报文即使丢失也能再传输,直到成功传输为止,从而保证可靠。

  4. 流量控制

    发送端如果数据发送过快,导致接收端的缓冲区很快就满了,如果持续下去,数据溢出缓冲区,就会出现数据丢失。这时需要在发送端和接收端有一个窗口,窗口的作用为:在发送缓冲区,只有在窗口里面的数据,才能被发送,在接收缓冲区,只有在窗口里的数据才能被接收,接收端收到数据之后,会回复ack,发送端会根据ack的值来判断接收能力,从而动态调整窗口大小,实现流量控制。

  5. 拥塞控制

    如果网络出现拥塞,TCP会根据不同情况,采用不同的算法:慢开始,拥塞避免,快重传,快恢复来对窗口大小cwnd和慢开始门限值ssthresh进行调整,从而降低网络拥塞的可能性。

4.3 ARQ协议

TCP保证可靠传输的确认应答和超时重传机制是靠ARQ协议实现的,ARQ协议:

  • ARQ(Automatic Repeat Quest)自动重传请求,是OSI模型中的错误纠正协议之一。

  • ARQ协议通过确认和重传这两个机制,在不可靠的基础上实现可靠的信息传输

  • 如果发送方在发送后的一段时间内没有收到确认帧,他通常会重新发送。

  • 重传的请求是自动进行的,接收方不需要请求发送方重传某个出错的分组。

4.3.1 停止等待ARQ协议

“停止等待”就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。

停止等待协议ARQ的优缺点:

4.3.1.1 无差错情况

4.3.1.2 出现差错情况

如果出现差错,会有两种差错情况:

  • B接收M1时检测出了差错,于是B就丢弃M1,其他什么也不做(不通知发送方A)
  • M1在传输过程中丢失了,这时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 流水线传输

为了提高传输效率,发送方可以不采用低效率的停止等待协议,而是采用流水线传输,即发送方可以连续发送多个分组,不必每发送完一个分组就停顿下来等待对方的确认,这样可以使信道上一直有数据不间断地传送。

流水线传输通常要求:

  • 必须增加序号范围。因为每个传输的分组必须有一个唯一的序号,可能存在有多个在传输中未确认的报文。
  • 发送方和接收方要能缓存多个分组,发送方至少要能缓存那些已发送但是没有被确认的分组,接收方要能缓存那些已正确接收到的分组。
  • 解决流水线传输的差错有两种滑动窗口协议:回退N(Go-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到底运行在那一层?

  1. ARQ是一种可以在不可靠的数据通道上可靠地传输数据的方案,所以其实链路层和传输层都用了ARQ,并不专属某一层。

  2. 并不是一条连接只要有一层用了ARQ,它的上层的通信就是可靠的。因为ARQ只保证使用它的点到点是可靠的,比如数据链路层只保证你和你的路由器通信可靠,你的路由器到小区的路由器通信也可靠, 但是路由器本身会故障,会拥塞丢包,也就是点本身会产生问题。

  3. 所以需要在传输层或者应用层再加一层ARQ保障整条数据通道的可靠性。比如你自己写程序要在应用层通信,但传输层不用TCP想用UDP,也可以在你程序里用ARQ协来实现可靠性。

4.4 三次握手

TCP 三次握手,其实就是 TCP 应用在发送数据前,通过 TCP 协议跟通信对方协商好连接信息,建立起TCP的连接关系。

TCP连接并非是在通信设备两端之间建立信号通道,而是双方各自维护所需的状态,已达到TCP连接的效果。

4.4.1 三次握手的步骤

  1. 初始:最初客户端和服务器都是处于CLOSED(关闭)状态。服务器进程创建传输控制块(TCB),被动打开,进入LISTEN(监听)状态,时刻准备接收客户端的连接请求。
  2. 第一次握手:客户端进程创建传输控制块(TCB),然后客户端给服务器发送一个连接请求报文,指明同步位SYN=1,且客户端的初始化序列号(ISN,Initial Sequence Number)seq=x。此时客户端处于SYN-SENT同步已发送)状态。SYN报文段不能携带数据,但是需要消耗掉一个序号。
  3. 第二次握手:服务器收到客户端的连接请求报文后,如果同意连接,则会向客户端发送确认报文。ACK=1,SYN=1,并且也指定了自己的初始化序列号(ISN)seq=y,同时ack=x+1(由于连接请求报文seq=x不携带数据,但消耗一个序号,所以ack=x+1),表示自己已经收到了客户端的SYN报文。此时服务器处于SYN_RCVD同步已收到)状态。确认报文也不能携带数据,也是仍然消耗一个序号。
  4. 第三次握手:客户端收到确认报文后,还要向服务器发出确认。确认报文的ACK=1,seq=y+1,自己的序列号为seq=x+1。此时,客户端进入ESTABLISHED(已建立连接)状态。当服务器收到客户端的确认后也进入ESTABLISHED(已建立连接)状态。此时,双方就可以进行数据传输了。

4.4.2 三次握手的作用

  1. 确认收发双方的发送、接收能力是否都正常
    • 第一次握手:客户端发,服务器收,这样服务器能够得出结论:客户端的发送能力、服务器的接收能力正常。
    • 第二次握手:服务器发,客户端收,这样客户端能够得出结论:客户端的发送、接收能力与服务器的发送、接收能力是正常的。所以第二次握手后,客户端就进入ESTABLISHED状态。
    • 第三次握手:此时服务器还不知道客户端的接收能力和服务器的发送能力是否正常。所以才有了第三次握手。客户端发,服务器收,这样服务器得出结论:客户端的发送、接收和服务器的发送、接收能力都是正常的。所以第三次握手后,服务器才进入ESTABLISHEDh状态。
  2. 指定自己的初始化序列号,为后面的可靠传送做准备

4.4.3 为什么需要最后一次握手

  1. 确认客户端和服务器双方的发送、接收能力是否均正常。如果只采用两次握手,服务器无法判断客户端的接收能力和服务器的发送能力是否正常
  2. 确认序列号的可靠同步。如果是两次握手,服务端无法确定客户端是否接收到了自己发送的初始序列号。如果第二次握手报文丢失,客户端无法知道服务端的初始序列号,那么TCP连接的可靠性无法保证。
  3. 阻止重复历史连接的初始化。客户端由于某种原因发送了两个不同序号的SYN报文,由于复杂的网络环境,有可能旧的SYN先到达服务器。采用三次握手,客户端在收到服务器发送的确认报文后,对比ack是对应旧的SYN报文还是新的SYN报文,如果是对应旧的,那么客户端就给服务器发送RST报文,直到正常的SYN到达服务器后才正常建立连接。
  4. 阻止超时请求建立连接浪费资源。如果一个连接请求在网络中传输的比较慢,超时后客户端会重新发送该连接请求,但是最后之前那个慢的连接请求最后还是到达了服务器。如果只采用两次握手的话,就会建立两个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 四次挥手的步骤

  1. 起初客户端和服务器都是处于ESTABLISHED状态。如果数据传输完毕,要释放连接,客户端主动关闭,服务器被动关闭。
  2. 客户端进程发出连接释放报文,并且停止发送数据。释放报文首部,FIN=1,序列号seq=u。此时客户端进入FIN-WAIT-1(终止等待1)状态。FIN报文即使不携带数据,也要消耗一个序号。
  3. 服务器收到连接释放报文后,发出确认报文。ACK=1,ack=u+1,并且带上自己的序号seq=v。此时服务器进入CLOSE-WAIT(关闭等待)状态。这时客户端向服务器方向的连接就释放了,处于半关闭状态,即客户端没有数据要发送了,但是服务器若发送数据,客户端依然接受。这个CLOSE-WAIT状态要持续一段时间,用于服务器把未发完的数据发送给客户端。
  4. 客户端收到服务器的确认请求后,客户端进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文。(在这之前还需要接收服务器发送的最后的数据)
  5. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ACK=1,ack=u+1,并带上自己的序号seq=w(在半关闭状态时服务器可能又发送了数据,所以序号由u变为w)。此时服务器就进入LAST-ACK(最后确认)状态,等待客户端的确认。
  6. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序号是seq=u+1。此时客户端进入了TIME-WAIT(时间等待)状态。此时TCP连接还没有释放,必须经过2*MSL(2倍的最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  7. 服务器只要收到了客户端发出的确认,立即进入CLOSED状态,并撤销TCB。
  8. 可以看到,服务器结束TCP连接的时间要比客户端早一些。

4.5.2 为什么最后客户端要等待2*MSL

  1. 保证客户端发送的最后一个ACK报文能够达到服务器。因为这个ACK报文有可能丢失,站在服务器的角度,我已经发送了FIN+ACK的释放报文,但是客户端没有给出确认,那我就认为是客户端没有收到我发送的释放报文,于是我就重新发送一次这个释放报文。这样客户端就能在这个2MSL(客户端ACK到达服务器 + 服务器发送 FIN重传包,一来一回)时间内收到这个重传的报文,并给出确认,并且重启2MSL计时器。如果等待 2MSL 时间也没有收到服务器端的重传包 FIN,说明可以确认服务器已经收到客户端发送的 ACK
  2. 防止类似于三次握手中提到的“已经失效的连接请求报文出现在本连接中”。客户端在发送完最后一个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发送了rwnd=0的报文段后,发送方就知道不再向接收方发送数据了。不久后,如果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,将阈值ssthresh=MAX/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。并把阈值ssthresh=MAX/2(注意MAX是出现超时的时候的拥塞窗口瓶颈值,可能是拥塞,也可能是丢包,所以只要出现超时时的拥塞窗口值就是MAX,它并不是固定不变的,而是根据具体超时情况改变的)。但是这时并非把拥塞窗口N设置为1,而是让N=ssthresh,并以拥塞避免的方式(线性增长)增大拥塞窗口。这种情况称之为“快恢复”。

4.9 拥塞控制和流量控制的区别

  • 拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况。
  • 流量控制是作用于接受者的,它是控制发送方的发送速率从而使接收方来得及接收,防止分组丢失。
  • 拥塞控制网络的拥堵情况相关联,而流量控制接收方的缓存状态相关联。
  • 拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。
  • 流量控制是点对点通信量的控制,是一个端到端的问题(接收端控制发送端)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算机网络笔记、面试八股(四)—— TCP连接 的相关文章

  • 基于labview实现MYSQL数据库查询功能

    前言 labview是一款功能强大的图形化编程软件 也就是俗称的G语言 本篇将介绍如何利用labview对MYSQL进行列表分页 范围查询及模糊查询等几个可广泛应用的简易功能 但事实上labview并不擅长处理数据库 下面详细代码可体现 数
  • spring-boot,java 微服务,跨域配置

    只需要在启动类下面与run方法同级加上下面那串代码即可 public static void main String args SpringApplication run ApplicationService class args Over
  • Visual Studio 2019中使用Qt,步骤详解

    本文学习的目的就是在Visual Studio 2019环境下能够顺利的运行Qt程序 下面是一些具体的配置安装过程 首先 打开visual Studio 2019 继续但无需代码 如图 然后点击扩展 管理扩展 在搜索框中搜索Qt 点击下载插

随机推荐

  • 上个厕所的功夫,就把定时任务的三种调度策略说得明明白白

    Spring Task 无疑是 Spring 环境下单机定时任务的首选 它用起来非常简单 功能也够用 Spring Task 有三种模式 分别是 fixedDelay cron 和 fixedRate 话不多说 我们先看代码 Slf4j C
  • JUC多线程及高并发

    文章目录 1 对volatile的理解 2 CAS 3 原子类AtomicInteger的ABA问题 原子更新引用 4 ArrayList线程不安全的案例 5 公平锁 非公平锁 可重入锁 递归锁 自旋锁 6 CountDownLatch C
  • SpringBoot支付宝沙箱支付步骤

    步骤1 注册一个沙箱号 网站https open alipay com platform home htm 使用自己真实的支付宝扫描进去 进行注册沙箱支付宝 步骤2 下载密匙生成工具 下载完毕 解压 双击运行 网址 https opendo
  • 重磅:国产IDE发布,由阿里研发,完全开源!​(高性能+高定制性)

    经历近 3 年时间 在阿里集团及蚂蚁集团共建小组的努力下 OpenSumi 作为国内首个强定制性 高性能 兼容 VS Code 插件体系的 IDE 研发框架 今天正式对外开源 1 OpenSumi 是什么 OpenSumi 是一款面向垂直领
  • Lua点号和冒号区别

    定义的时候冒号默认接收self参数 调用的时候冒号默认传递调用者自己为参数 而句号要显示传递或接收self参数 例如 句号定义 需要显示传递或接收 plain view plain copy a x 1 function a fun sel
  • Python画QQ图检验正态分布

    import numpy as np import seaborn as sns import matplotlib pyplot as plt from statsmodels graphics api import qqplot sns
  • pip 安装 sklearn or scikit-learn python3

    安装 sklearn 1 安装 numpy scipy matplot pip3 install numpy scipy matplotlib i https pypi tuna tsinghua edu cn simple 2 安装 sk
  • Android序列化:Serializable Parcelable

    Android序列化完全解析 一 Java Serializable http http www jianshu com p fcc59fb523b6 Android序列化完全解析 二 Parcelable http www jianshu
  • 背对背mos管开关_10天电子入门-MOS管

    1 MOS管介绍 在各大IT企中我们把场效应管 FET 统称为MOS管 其作用是把输入电压的变化转化为输出电流的变化 FET的增益等于它的跨导 定义为输出电流的变化和输入电压变化之比 市面上常有的一般为N沟道和P沟道 它属于电压控制型半导体
  • uni-app 之 解决u-button始终居中问题

    uView中u button始终居中问题如何解决的简单方法 1 给该元素margin right 0 可以达到向右靠齐 2 给该元素的父元素设置float right image png
  • DF-GAN: A Simple and Effective Baseline for Text-to-Image Synthesis论文解读

    题目 DF GAN 一种简单有效的文本 图像合成基线 时间 2022 CVPR Abstract 从文字描述中合成高质量的逼真图像是一项具有挑战性的任务 现有的文本 图像生成对抗网络通常采用堆叠架构作为主干 但仍存在三个缺陷 首先 分层结构
  • open3d,读取stl/ply/obj/off/gltf/glb三维模型,并转换成点云,保存

    1 三维模型获取 可以自己用建模软件建立一个模型 本案例使用模型的下载地址 可以从free3d免费下载 无需注册 2 导入open3d import open3d as o3d 3 open3d模型读取与可视化 模型路径 支持后缀 stl
  • vim编辑器-设置默认行号和高级用法

    vim 自动显示行号 编辑 etc vim vimrc文件 在最后加上两句 完事ok 注 set nu 显示行号 set tabstop 4 设置缩进 set nonumber取消行号 set nu set tabstop 4 vim的高级
  • SpringBoot2为什么默认使用CGLib不再使用JDK动态代理

    SpringBoot2为什么默认使用CGLib不再使用JDK动态代理 CGLib和JDK动态代理对比 1 不需要实现接口 2 性能 3 代理对象的创建 4 调用方法 2 CGLib使用 CGLib和JDK动态代理对比 1 不需要实现接口 J
  • hadoop 配置history server 和timeline server

    一 配置history server 1 配置history server 在etc hadoop mapred site xml中配置以下内容 span style font size 18px span style font size
  • python工程师-Python工程师学习之旅

    1 Python软件开发基础 1 Linux操作系统2 Docker基础3 Python基础语法4 Python字符串解析5 Python正则表达式6 Python文件操作7 Python 模块8 Python异常9 python GUI编
  • 施密特触发器的作用-摘录+自解

    波形变换 可将三角波 正弦波 周期性波等变成矩形波 脉冲波的整形 数字系统中 矩形脉冲在传输中经常发生波形畸变 出现上升沿和下降沿不理想的情况 可用施密特触发器整形后 获得较理想的矩形脉冲 脉冲鉴幅 幅度不同 不规则的脉冲信号施加到施密特触
  • Opencv 视频帧的读写处理指导

    Opencv 视频帧的读写指导 思路指导 1 先打开视频文件 2 遍历视频帧 3 处理视频帧 4 保存所有的视频帧 1 打开视频 1 当读取的是保存的视频时 打开视频的方法为 cv VideoCapture capture 视频名 将视频放
  • el-tree处理树形结构的穿梭框问题(后台返回平级数据 / 文末附项目Git地址)

    作者简介 一个每天中午去打篮球和锻炼的前端开发 两只猫 和一只狗的铲屎官 微博 GuoJ阝阝 fu 文章目录 前言 一 分析需求 二 使用步骤 1 引入库 2 页面文件代码 3 功能函数代码 4 引入的javaScript文件的代码 三 项
  • 计算机网络笔记、面试八股(四)—— TCP连接

    本章目录 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