滴滴工程师图文并茂带你深入理解 TCP 握手分手全过程

TCP 连接管理机制(一)——TCP三次握手详解 + 为什么要有三次握手 TCP三次握手的状态变化以及 为什么要有三次握手 阅读详情

640?wx_fmt=jpeg

本文作者:饶全成,中科院计算所硕士,滴滴出行后端研发工程师。

个人主页:

https://zhihu.com/people/raoquancheng

记得刚毕业找工作面试的时候,经常会被问到:你知道“3次握手,4次挥手”吗?这时候我会“胸有成竹”地“背诵”前期准备好的“答案”,第一次怎么怎么,第二次……答完就没有下文了,面试官貌似也没有深入下去的意思,深入下去我也不懂,皆大欢喜!

作为程序员,要有“刨根问底”的精神。知其然,更要知其所以然。这篇文章希望能抽丝剥茧,还原背后的原理。

什么是“3次握手,4次挥手”

TCP是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓的“连接”,其实是客户端和服务器的内存里保存的一份关于对方的信息,如ip地址、端口号等。

TCP可以看成是一种字节流,它会处理IP层或以下的层的丢包、重复以及错误问题。在连接的建立过程中,双方需要交换一些连接的参数。这些参数可以放在TCP头部。

TCP提供了一种可靠、面向连接、字节流、传输层的服务,采用三次握手建立一个连接。采用4次挥手来关闭一个连接。

TCP服务模型

在了解了建立连接、关闭连接的“三次握手和四次挥手”后,我们再来看下TCP相关的东西。

一个TCP连接由一个4元组构成,分别是两个IP地址和两个端口号。一个TCP连接通常分为三个阶段:启动、数据传输、退出(关闭)。

当TCP接收到另一端的数据时,它会发送一个确认,但这个确认不会立即发送,一般会延迟一会儿。ACK是累积的,一个确认字节号N的ACK表示所有直到N的字节(不包括N)已经成功被接收了。这样的好处是如果一个ACK丢失,很可能后续的ACK就足以确认前面的报文段了。

一个完整的TCP连接是双向和对称的,数据可以在两个方向上平等地流动。给上层应用程序提供一种双工服务。一旦建立了一个连接,这个连接的一个方向上的每个TCP报文段都包含了相反方向上的报文段的一个ACK。

序列号的作用是使得一个TCP接收端可丢弃重复的报文段,记录以杂乱次序到达的报文段。因为TCP使用IP来传输报文段,而IP不提供重复消除或者保证次序正确的功能。另一方面,TCP是一个字节流协议,绝不会以杂乱的次序给上层程序发送数据。因此TCP接收端会被迫先保持大序列号的数据不交给应用程序,直到缺失的小序列号的报文段被填满。

TCP头部

640?wx_fmt=jpeg

源端口和目的端口在TCP层确定双方进程,序列号表示的是报文段数据中的第一个字节号,ACK表示确认号,该确认号的发送方期待接收的下一个序列号,即最后被成功接收的数据字节序列号加1,这个字段只有在ACK位被启用的时候才有效。

当新建一个连接时,从客户端发送到服务端的第一个报文段的SYN位被启用,这称为SYN报文段,这时序列号字段包含了在本次连接的这个方向上要使用的第一个序列号,即初始序列号ISN,之后发送的数据是ISN加1,因此SYN位字段会消耗一个序列号,这意味着使用重传进行可靠传输。而不消耗序列号的ACK则不是。

头部长度(图中的数据偏移)以32位字为单位,也就是以4bytes为单位,它只有4位,最大为15,因此头部最大长度为60字节,而其最小为5,也就是头部最小为20字节(可变选项为空)。

ACK —— 确认,使得确认号有效。 RST —— 重置连接(经常看到的reset by peer)就是此字段搞的鬼。 SYN —— 用于初如化一个连接的序列号。 FIN —— 该报文段的发送方已经结束向对方发送数据。

当一个连接被建立或被终止时,交换的报文段只包含TCP头部,而没有数据。

状态转换

三次握手和四次挥手的状态转换如下图。

640?wx_fmt=jpeg

为什么要“三次握手,四次挥手”

三次握手

换个易于理解的视角来看为什么要3次握手。

客户端和服务端通信前要进行连接,“3次握手”的作用就是双方都能明确自己和对方的收、发能力是正常的。

第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。

第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。 从客户端的视角来看,我接到了服务端发送过来的响应数据包,说明服务端接收到了我在第一次握手时发送的网络包,并且成功发送了响应数据包,这就说明,服务端的接收、发送能力正常。而另一方面,我收到了服务端的响应数据包,说明我第一次发送的网络包成功到达服务端,这样,我自己的发送和接收能力也是正常的。

第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力,服务端的发送、接收能力是正常的。 第一、二次握手后,服务端并不知道客户端的接收能力以及自己的发送能力是否正常。而在第三次握手时,服务端收到了客户端对第二次握手作的回应。从服务端的角度,我在第二次握手时的响应数据发送出去了,客户端接收到了。所以,我的发送能力是正常的。而客户端的接收能力也是正常的。

经历了上面的三次握手过程,客户端和服务端都确认了自己的接收、发送能力是正常的。之后就可以正常通信了。

每次都是接收到数据包的一方可以得到一些结论,发送的一方其实没有任何头绪。我虽然有发包的动作,但是我怎么知道我有没有发出去,而对方有没有接收到呢?

而从上面的过程可以看到,最少是需要三次握手过程的。两次达不到让双方都得出自己、对方的接收、发送能力都正常的结论。其实每次收到网络包的一方至少是可以得到:对方的发送、我方的接收是正常的。而每一步都是有关联的,下一次的“响应”是由于第一次的“请求”触发,因此每次握手其实是可以得到额外的结论的。比如第三次握手时,服务端收到数据包,表明看服务端只能得到客户端的发送能力、服务端的接收能力是正常的,但是结合第二次,说明服务端在第二次发送的响应包,客户端接收到了,并且作出了响应,从而得到额外的结论:客户端的接收、服务端的发送是正常的。

用表格总结一下:

640?wx_fmt=jpeg

四次挥手

TCP连接是双向传输的对等的模式,就是说双方都可以同时向对方发送或接收数据。当有一方要关闭连接时,会发送指令告知对方,我要关闭连接了。这时对方会回一个ACK,此时一个方向的连接关闭。但是另一个方向仍然可以继续传输数据,等到发送完了所有的数据后,会发送一个FIN段来关闭此方向上的连接。接收方发送ACK确认关闭连接。注意,接收到FIN报文的一方只能回复一个ACK, 它是无法马上返回对方一个FIN报文段的,因为结束数据传输的“指令”是上层应用层给出的,我只是一个“搬运工”,我无法了解“上层的意志”。

“三次握手,四次挥手”怎么完成?

其实3次握手的目的并不只是让通信双方都了解到一个连接正在建立,还在于利用数据包的选项来传输特殊的信息,交换初始序列号ISN。

3次握手是指发送了3个报文段,4次挥手是指发送了4个报文段。注意,SYN和FIN段都是会利用重传进行可靠传输的。

640?wx_fmt=jpeg

三次握手

  1. 客户端发送一个SYN段,并指明客户端的初始序列号,即ISN(c).

  2. 服务端发送自己的SYN段作为应答,同样指明自己的ISN(s)。为了确认客户端的SYN,将ISN(c)+1作为ACK数值。这样,每发送一个SYN,序列号就会加1. 如果有丢失的情况,则会重传。

  3. 为了确认服务器端的SYN,客户端将ISN(s)+1作为返回的ACK数值。

四次挥手

640?wx_fmt=jpeg

1. 客户端发送一个FIN段,并包含一个希望接收者看到的自己当前的序列号K. 同时还包含一个ACK表示确认对方最近一次发过来的数据。 2. 服务端将K值加1作为ACK序号值,表明收到了上一个包。这时上层的应用程序会被告知另一端发起了关闭操作,通常这将引起应用程序发起自己的关闭操作。 3. 服务端发起自己的FIN段,ACK=K+1, Seq=L 4. 客户端确认。ACK=L+1

为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方是否现在关闭发送数据通道,需要上层应用来决定,因此,己方ACK和FIN一般都会分开发送。

“三次握手,四次挥手”进阶

ISN

三次握手的一个重要功能是客户端和服务端交换ISN(Initial Sequence Number), 以便让对方知道接下来接收数据的时候如何按序列号组装数据。

如果ISN是固定的,攻击者很容易猜出后续的确认号。

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

M是一个计时器,每隔4毫秒加1。 F是一个Hash算法,根据源IP、目的IP、源端口、目的端口生成一个随机数值。要保证hash算法不能被外部轻易推算得出。

序列号回绕

因为ISN是随机的,所以序列号容易就会超过2^31-1. 而tcp对于丢包和乱序等问题的判断都是依赖于序列号大小比较的。此时就出现了所谓的tcp序列号回绕(sequence wraparound)问题。怎么解决?

/** The next routines deal with comparing 32 bit unsigned ints
 * and worry about wraparound (automatic with unsigned arithmetic).*/

static inline int before(__u32 seq1, __u32 seq2){
    return (__s32)(seq1-seq2) < 0;}

#define after(seq2, seq1) before(seq1, seq2)

上述代码是内核中的解决回绕问题代码。s32是有符号整型的意思,而u32则是无符号整型。序列号发生回绕后,序列号变小,相减之后,把结果变成有符号数了,因此结果成了负数。

假设seq1=255, seq2=1(发生了回绕)。
seq1 = 1111 1111 seq2 = 0000 0001
我们希望比较结果是
 seq1 - seq2=
 1111 1111
-0000 0001
-----------
 1111 1110

由于我们将结果转化成了有符号数,由于最高位是1,因此结果是一个负数,负数的绝对值为
 0000 0001 + 1 = 0000 0010 = 2

因此seq1 - seq2 < 0

syn flood攻击

最基本的DoS攻击就是利用合理的服务请求来占用过多的服务资源,从而使合法用户无法得到服务的响应。syn flood属于Dos攻击的一种。

如果恶意的向某个服务器端口发送大量的SYN包,则可以使服务器打开大量的半开连接,分配TCB(Transmission Control Block), 从而消耗大量的服务器资源,同时也使得正常的连接请求无法被相应。当开放了一个TCP端口后,该端口就处于Listening状态,不停地监视发到该端口的Syn报文,一 旦接收到Client发来的Syn报文,就需要为该请求分配一个TCB,通常一个TCB至少需要280个字节,在某些操作系统中TCB甚至需要1300个字节,并返回一个SYN ACK命令,立即转为SYN-RECEIVED即半开连接状态。系统会为此耗尽资源。

常见的防攻击方法有:

无效连接的监视释放

监视系统的半开连接和不活动连接,当达到一定阈值时拆除这些连接,从而释放系统资源。这种方法对于所有的连接一视同仁,而且由于SYN Flood造成的半开连接数量很大,正常连接请求也被淹没在其中被这种方式误释放掉,因此这种方法属于入门级的SYN Flood方法。

延缓TCB分配方法

消耗服务器资源主要是因为当SYN数据报文一到达,系统立即分配TCB,从而占用了资源。而SYN Flood由于很难建立起正常连接,因此,当正常连接建立起来后再分配TCB则可以有效地减轻服务器资源的消耗。常见的方法是使用Syn Cache和Syn Cookie技术。

Syn Cache技术

系统在收到一个SYN报文时,在一个专用HASH表中保存这种半连接信息,直到收到正确的回应ACK报文再分配TCB。这个开销远小于TCB的开销。当然还需要保存序列号。

Syn Cookie技术

Syn Cookie技术则完全不使用任何存储资源,这种方法比较巧妙,它使用一种特殊的算法生成Sequence Number,这种算法考虑到了对方的IP、端口、己方IP、端口的固定信息,以及对方无法知道而己方比较固定的一些信息,如MSS(Maximum Segment Size,最大报文段大小,指的是TCP报文的最大数据报长度,其中不包括TCP首部长度。)、时间等,在收到对方 的ACK报文后,重新计算一遍,看其是否与对方回应报文中的(Sequence Number-1)相同,从而决定是否分配TCB资源。

使用SYN Proxy防火墙

一种方式是防止墙dqywb连接的有效性后,防火墙才会向内部服务器发起SYN请求。防火墙代服务器发出的SYN ACK包使用的序列号为c, 而真正的服务器回应的序列号为c', 这样,在每个数据报文经过防火墙的时候进行序列号的修改。另一种方式是防火墙确定了连接的安全后,会发出一个safe reset命令,client会进行重新连接,这时出现的syn报文会直接放行。这样不需要修改序列号了。但是,client需要发起两次握手过程,因此建立连接的时间将会延长。

连接队列

在外部请求到达时,被服务程序最终感知到前,连接可能处于SYN_RCVD状态或是ESTABLISHED状态,但还未被应用程序接受。

640?wx_fmt=jpeg

对应地,服务器端也会维护两种队列,处于SYN_RCVD状态的半连接队列,而处于ESTABLISHED状态但仍未被应用程序accept的为全连接队列。如果这两个队列满了之后,就会出现各种丢包的情形。

查看是否有连接溢出
netstat -s | grep LISTEN

半连接队列满了

在三次握手协议中,服务器维护一个半连接队列,该队列为每个客户端的SYN包开设一个条目(服务端在接收到SYN包的时候,就已经创建了request_sock结构,存储在半连接队列中),该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。

目前,Linux下默认会进行5次重发SYN-ACK包,重试的间隔时间从1s开始,下次的重试间隔时间是前一次的双倍,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s, 总共31s, 称为指数退避,第5次发出后还要等32s才知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 63s, TCP才会把断开这个连接。由于,SYN超时需要63秒,那么就给攻击者一个攻击服务器的机会,攻击者在短时间内发送大量的SYN包给Server(俗称SYN flood攻击),用于耗尽Server的SYN队列。对于应对SYN 过多的问题,linux提供了几个TCP参数:tcp_syncookies、tcp_synack_retries、tcp_max_syn_backlog、tcp_abort_on_overflow 来调整应对。
640?wx_fmt=jpeg

全连接队列满

当第三次握手时,当server接收到ACK包之后,会进入一个新的叫 accept 的队列。

当accept队列满了之后,即使client继续向server发送ACK的包,也会不被响应,此时ListenOverflows+1,同时server通过tcp_abort_on_overflow来决定如何返回,0表示直接丢弃该ACK,1表示发送RST通知client;相应的,client则会分别返回read timeout 或者 connection reset by peer。另外,tcp_abort_on_overflow是0的话,server过一段时间再次发送syn+ack给client(也就是重新走握手的第二步),如果client超时等待比较短,就很容易异常了。而客户端收到多个 SYN ACK 包,则会认为之前的 ACK 丢包了。于是促使客户端再次发送 ACK ,在 accept队列有空闲的时候最终完成连接。若 accept队列始终满员,则最终客户端收到 RST 包(此时服务端发送syn+ack的次数超出了tcp_synack_retries)。

服务端仅仅只是创建一个定时器,以固定间隔重传syn和ack到服务端

640?wx_fmt=jpeg

命令

netstat -s命令

[root@server ~]# netstat -s | egrep "listen|LISTEN" 667399 times the listen queue of a socket overflowed 667399 SYNs to LISTEN sockets ignored
比如上面看到的 667399 times ,表示全连接队列溢出的次数,隔几秒钟执行下,如果这个数字一直在增加的话肯定全连接队列偶尔满了。
[root@server ~]# netstat -s | grep TCPBacklogDrop 查看 Accept queue 是否有溢出

ss命令

[root@server ~]# ss -lnt State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 :6379 : LISTEN 0 128 :22 : 如果State是listen状态,Send-Q 表示第三列的listen端口上的全连接队列最大为50,第一列Recv-Q为全连接队列当前使用了多少。 非 LISTEN 状态中 Recv-Q 表示 receive queue 中的 bytes 数量;Send-Q 表示 send queue 中的 bytes 数值。

小结

当外部连接请求到来时,TCP模块会首先查看max_syn_backlog,如果处于SYN_RCVD状态的连接数目超过这一阈值,进入的连接会被拒绝。根据tcp_abort_on_overflow字段来决定是直接丢弃,还是直接reset.

从服务端来说,三次握手中,第一步server接受到client的syn后,把相关信息放到半连接队列中,同时回复syn+ack给client. 第三步当收到客户端的ack, 将连接加入到全连接队列。

一般,全连接队列比较小,会先满,此时半连接队列还没满。如果这时收到syn报文,则会进入半连接队列,没有问题。但是如果收到了三次握手中的第3步(ACK),则会根据tcp_abort_on_overflow字段来决定是直接丢弃,还是直接reset.此时,客户端发送了ACK, 那么客户端认为三次握手完成,它认为服务端已经准备好了接收数据的准备。但此时服务端可能因为全连接队列满了而无法将连接放入,会重新发送第2步的syn+ack, 如果这时有数据到来,服务器TCP模块会将数据存入队列中。一段时间后,client端没收到回复,超时,连接异常,client会主动关闭连接。

“三次握手,四次挥手”redis实例分析

  1. 我在dev机器上部署redis服务,端口号为6379,

  2. 通过tcpdump工具获取数据包,使用如下命令

tcpdump -w /tmp/a.cap port 6379 -s0
-w把数据写入文件,-s0设置每个数据包的大小默认为68字节,如果用-S 0则会抓到完整数据包
  1. 在dev2机器上用redis-cli访问dev:6379, 发送一个ping, 得到回复pong

  2. 停止抓包,用tcpdump读取捕获到的数据包

tcpdump -r /tmp/a.cap -n -nn -A -x| vim -
(-x 以16进制形式展示,便于后面分析)

共收到了7个包。

抓到的是IP数据包,IP数据包分为IP头部和IP数据部分,IP数据部分是TCP头部加TCP数据部分。

IP的数据格式为:

640?wx_fmt=jpeg

它由固定长度20B+可变长度构成。

10:55:45.662077 IP dev2.39070 > dev.6379: Flags [S], seq 4133153791, win 29200, options [mss 1460,sackOK,TS val 2959270704 ecr 0,nop,wscale 7], length 0
        0x0000:  4500 003c 08cf 4000 3606 14a5 0ab3 b561
        0x0010:  0a60 5cd4 989e 18eb f65a ebff 0000 0000
        0x0020:  a002 7210 872f 0000 0204 05b4 0402 080a
        0x0030:  b062 e330 0000 0000 0103 0307

对着IP头部格式,来拆解数据包的具体含义。

640?wx_fmt=jpeg

剩余的数据部分即为TCP协议相关的。TCP也是20B固定长度+可变长度部分。

640?wx_fmt=jpeg

可变长度部分,协议如下:

640?wx_fmt=jpeg

这样第一个包分析完了。dev2向dev发送SYN请求。也就是三次握手中的第一次了。 SYN seq(c)=4133153791

第二个包,dev响应连接,ack=4133153792. 表明dev下次准备接收这个序号的包,用于tcp字节注的顺序控制。dev(也就是server端)的初始序号为seq=4264776963, syn=1. SYN ack=seq(c)+1 seq(s)=4264776963

第三个包,client包确认,这里使用了相对值应答。seq=4133153792, 等于第二个包的ack. ack=4264776964. ack=seq(s)+1, seq=seq(c)+1 至此,三次握手完成。接下来就是发送ping和pong的数据了。

接着第四个包。

10:55:48.090073 IP dev2.39070 > dev.6379: Flags [P.], seq 1:15, ack 1, win 229, options [nop,nop,TS val 2959273132 ecr 3132256230], length 14
        0x0000:  4500 0042 08d1 4000 3606 149d 0ab3 b561
        0x0010:  0a60 5cd4 989e 18eb f65a ec00 fe33 5504
        0x0020:  8018 00e5 4b5f 0000 0101 080a b062 ecac
        0x0030:  bab2 6fe6 2a31 0d0a 2434 0d0a 7069 6e67
        0x0040:  0d0a

tcp首部长度为32B, 可选长度为12B. IP报文的总长度为66B, 首部长度为20B, 因此TCP数据部分长度为14B. seq=0xf65a ec00=4133153792 ACK, PSH. 数据部分为2a31 0d0a 2434 0d0a 7069 6e67 0d0a

0x2a31         -> *1
0x0d0a         -> \r\n
0x2434         -> $4
0x0d0a         -> \r\n
0x7069 0x6e67  -> ping
0x0d0a         -> \r\n

dev2向dev发送了ping数据,第四个包完毕。

第五个包,dev2向dev发送ack响应。 序列号为0xfe33 5504=4264776964, ack确认号为0xf65a ec0e=4133153806=(4133153792+14).

第六个包,dev向dev2响应pong消息。序列号fe33 5504,确认号f65a ec0e, TCP头部可选长度为12B, IP数据报总长度为59B, 首部长度为20B, 因此TCP数据长度为7B. 数据部分2b50 4f4e 470d 0a, 翻译过来就是+PONG\r\n.

至此,Redis客户端和Server端的三次握手过程分析完毕。

点击「阅读原文」,给本文作者饶全成点赞

640?wx_fmt=png

大拇指长按图片识别二维码,阅读更多深度内容

TCP的三次握手及四次挥手详解 三次握手 三次握手过程: (1)第一次握手:Client将标志位SYN置为1(表示要发起一个连接),随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。 (2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。 (3)... 阅读详情

相关推荐

TCP三次握手详解-深入浅出(有图实例演示)

TCP是属于网络分层中的传输层,因为OSI分为层,感觉太麻烦了,所以分为四层就好了,简单。 分层以及每层的协议,如下两张图: TCP三次握手 TCP三次握手简单如下图: TCP三次握手的过程描述: 1.客户主动(active open)去connect服务器,并且发送SYN 假设序列号为J, 服务器是被动打开(passive open) 2.服务器在收到SYN后,它...

jun2016425的博客 32万+

一文搞懂TCP的三次握手和四次挥手

一文搞懂TCP的三次握手和四次挥手

不脱发的程序猿 19万+

eNSP无法启动AR报错码40,而且按照eNSP帮助手册排查都没用,我的处理方法【自己存档版】

eNSP无法启动AR报错码40,而且按照eNSP帮助手册排查都没用,我的处理方法【自己存档版】

mizhiakk的博客 8426

【通俗易懂】三次握手与四次挥手

三次握手 1.1三次握手(Three-way Handshake)是指在建立一个TCP连接时,客户端和服务器会一共发送三个报文段。 初始时客户端和服务器都处于CLOSED状态,当服务器应用程序创建一个监听套接字时,服务器处于LISTEN状态。 1.第一次握手:客户端向服务器发送一个SYN报文段,报文段的首部中的标志位SYN置为1,另外还会指明客户端的初始化序列号ISN(seq=x),此时客户端处于SYN_SENT状态。 2.第二次握手:服务器收到SYN的报文段后,会以自己的SYNACK报文进行应答。该应答报

m0_52373742的博客 5万+

从基础知识到PCB设计,打造全能硬件工程师

成为一名出色的硬件工程师需要在多个领域建立坚实的基础。从硬件基础知识、元器件学习、模拟电子电路到PCB设计,以及数字电子电路与通信,每个方面都是构建全面硬件工程师技能集的重要组成部分。通过深入学习和实践这些领域,你将能够在硬件工程领域中取得更多的成就。

weixin_46969363的博客 2725

海思MPP平台千兆以太网驱动集成与测试指南

千兆以太网(GE)是嵌入式视觉系统中音视频流传输与边缘控制的核心物理接口,其底层驱动需兼顾DMA高效调度、中断实时响应与PHY链路稳定性。在Linux嵌入式环境中,GE驱动通常基于net_device框架实现,并深度耦合于SoC专用媒体处理平台(如海思MPP),通过硬件抽象层(HAL)屏蔽寄存器操作,提供零拷贝、RGMII时序适配、描述符环管理等关键能力。技术价值体现在降低CPU负载、保障1080p@30fps实时推流、支持ONVIF/RTSP协议交互及固件远程升级。典型应用场景包括网络摄像机(IPC)、A

weixin_42599908的博客 90

TCP四次挥手详解(含常见面试题)

TCP四次挥手过程 客户端发起fin位为1的FIN报文,此时客户端进入FIN_WAIT_1状态 服务端接受到FIN 报文后,发送ack应答报文,此时服务端进入close_wait状态 客户端接受到ack应答报文后,进入FIN_WAIT_2状态 服务端处理完数据后,向客户端发送FIN报文,此时服务端进入LAST_ACK状态 客户端接受到FIN报文后,客户端发送应答ack报文,进入TIME_WAIT阶段 服务端接受到ack报文后,断开连接,处于close状态 客户端过一段时间后,也就是2MSL后,进入clos

small_engineer的博客 2万+

半导体物理-Si晶体生长方向<2>

Si(硅)晶体的生长方向是一个重要的概念,尤其在半导体工业中。这个概念涉及到晶体在生长过程中原子排列的方向,对晶体的性质和应用有重大影响。让我为您详细解释:理解Si晶体的生长方向对于半导体材料的研究和应用非常重要,它直接影响了最终器件的性能和制造工艺。在实际应用中,选择适当的生长方向可以优化器件性能,提高产品质量。

m0_37606066的博客 3001

TCP连接的“三次握手”与“4次挥手”

“三次握手”:所谓的三次握手即TCP连接的建立。这个连接必须是一方主动打开,另一方被动打开的。 以下为客户端主动发起连接的图解: 握手之前主动打开连接的客户端结束CLOSED阶段,被动打开的服务器端也结束CLOSED阶段,并进入LISTEN阶段。随后开始“三次握手”: (1)首先客户端向服务器端发送一段TCP报文,其中:标记位为SYN,表示“请求建立新连接”;序号为Seq=X(X一般为1);随后客户端进入SYN-SENT阶段。 (2)服务器端接收到来自客户端的TCP报文之后,结束LISTE.

corner_dust的专栏 829

SQL面试题——抖音SQL面试题 股票波峰波谷

这个题目的难度比较低,我们是用lead 和 lag 两个函数就可以搞定,也就是在一个SQL 里面同时使用多个函数,问题的考查点在于对边界的考虑。

2万+

米哈游运维面试题及参考答案

Linux 系统运行级别是用于定义系统启动时所需要达到的功能状态。运行级别 0:表示系统停机状态,用于关闭系统,是系统的关机级别。当系统切换到这个级别时,会停止所有的服务和进程,然后关闭系统。运行级别 1:也称为单用户模式。在这个级别下,系统只启动基本的系统服务和必要的进程,仅允许 root 用户登录系统进行维护操作,常用于系统出现故障需要紧急修复的情况,比如修复文件系统错误、重置 root 密码等。运行级别 2:多用户模式,但不支持网络文件系统(NFS)。

大模型大数据攻城狮的专栏 746

两张动图-彻底明白TCP的三次握手与四次挥手

两张动图解析三次握手,四次挥手

qzcsu的博客 50万+

拆开它的“身体”,看懂割草机器人的五层系统架构

这篇文章深入解析了智能割草机器人的五层系统架构。机械层采用铝合金一体式车架和独立悬挂刀盘系统;电子层配备双处理器和多种传感器;固件层实现毫秒级安全响应;算法层融合多种定位技术实现厘米级精度;云服务层提供远程管理和AI优化。这套系统通过精密协同实现了智能割草的全流程闭环,展现了从机械结构到云端智能的完整技术栈,为户外智能设备设立了新的技术标杆。

智能硬件研发,欢迎交流 200

计算机网络之TCP四次挥手

计算机网络之四次握手

weixin_52690231的博客 1万+

Cyclone DDS背景技术

DDSI标准与DDS 1.2和1.4标准密切相关,DDSI中的实体与DCPS中的实体之间有明确的对应关系。但是,这种对应关系不是一一对应的。 此处,仅仅对DDSI规范的概念进行描述,暂不涉及Eclipse Cyclone DDS实现的细节。DDSI规范的概念将帮助对互操作性interoperability感兴趣的技术人员了解规范的外延边界和Eclipse Cyclone DDS实现的开始。

pony12的专栏 949

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

TCP 三次握手和四次挥手

TCP 三次握手和四次挥手

We choose to go to the moon in this decade and do the other things, not because they are easy, but beacase they are hard. 2万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

TCP四次挥手

我们知道TCP协议是有连接的,可靠性传输,全双工,面向字节流的传输层协议, 使用TCP协议在客户端和发送端传输数据前,必须先建立连接,传输数据完成之后,就要断开连接.而对于四次挥手来说就是用来TCP断开连接的.

欢迎来到我的博客,在这里我会用我的方式来讲解知识,请大家多多关照 5387

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【转】计算机网络——三次握手与四次挥手

【转】计算机网络——三次握手与四次挥手

NRWHF的博客 8851

TCP三次握手与四次挥手详解

本文详细介绍了TCP连接中的三次握手和四次挥手的原理,并在此基础上,详细介绍了其衍生的十多个面试问题。

青灯文案的博客 1万+

TCP连接管理——三次握手和四次挥手

TCP连接的建立——三次握手 TCP连接的建立过程通常被称为“三次握手”。客户端与服务器之间建立TCP连接的过程如下。 三次握手 客户端向服务器发送一个特殊的TCP报文段——SYN报文段。它不包含数据,但是会将TCP首部的SYN设置为1。并且,客户端会随机生成一个初始序号(client_isn)放在该报文段的序号字段中。随机生成序号有利于避免某些网络攻击。 服务器接收客户端发...

zy010101博客 7803

TCP三次握手(详解)

一:引出 客户端与服务器之间数据的发送和返回的过程当中需要创建一个叫TCP connection的东西;由于TCP不存在连接的概念,只存在请求和响应,请求和响应都是数据包,它们之间都是经过由TCP创建的一个从客户端发起,服务器接收的类似连接的通道,这个连接可以一直保持,http请求是在这个连接的基础上发送的;在一个TCP的连接上是可以发送多个http请求的 二:TCP的报文格式 1:TCP在传输层和网络层数据传输的过程 TCP协议是在传输层端到端的传输信息,既然说到传输层协议,那么就讲一下传输层协议在数据传

qq_48508278的博客 9万+

详解 TCP 连接的“ 三次握手 ”与“ 四次挥手 ”

详解 TCP 连接的“ 三次握手 ”与“ 四次挥手 ”1. TCP的三次握手(Three-Way Handshake)1.2 “三次握手”的通俗理解2. “四次挥手”(Four-Way Wavehand) 1. TCP的三次握手(Three-Way Handshake) 所谓的三次握手即TCP连接的建立。这个连接必须是一方主动打开,另一方被动打开的。以下为客户端主动发起连接的图解: 握手之前主动打开连接的客户端结束CLOSED阶段,被动打开的服务器端也结束CLOSED阶段,并进入LISTEN阶段。随后开始

weixin_59663288的博客 1万+

TCP/IP 三次握手

TCP/IP 三次握手

喵酱 1万+

TCP三次握手和四次挥手

一、三次握手 三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。 刚开始时客户端处于Closed的状态,服务端处于Listen状态。 进行三次握手: 第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN。此时客户端处于 SYN_SENT 状态。 首部的同步位SYN=1,初始序号seq=x,SYN=

kking_edc的博客 1万+

详解 TCP 连接的“三次握手”与“四次挥手”

详解 TCP 连接的“三次握手”与“四次挥手”前言TCP的三次握手(Three-Way Handshake)1.”三次握手”的详解2.“三次握手”的通俗理解3.为什么要进行第三次握手TCP的四次挥手(Four-Way Wavehand)1.“四次挥手”的详解2.“四次挥手”的通俗理解为什么“握手”是三次,“挥手”却要四次?为什么客户端在TIME-WAIT阶段要等2MSL? 前言 客户端与服务器之间数据的发送和返回的过程当中需要创建一个叫TCP connection的东西; 由于TCP不存在连接的概

spade_Kwo的博客 2万+
上一篇: 阿里巴巴开源限流系统 Sentinel 全解析
下一篇: 网易工程师 Ruheng 一文教你轻松学会 Git
码洞
博客等级 码龄10年 41粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值