TCP的三次握手与四次挥手
1.网络分层
网络分层 | 代表硬件 | 协议/技术 | 特性 |
---|---|---|---|
应用层 | HTTP,DNS,FTP,SMTP,Telnet协议等 | 应用程序实现的,规定应用程序的数据格式 | |
传输层 | TCP/UDP协议 | 负责两主机之间的数据正确传输主机系统内核实现的 | |
网络层 | 路由器 | IP协议 | 负责地址管理和路由选择(确定对应主机),如何将数据从发送方路由到接收方 |
数据链路层 | 交换机 | 以太网,令牌环网,无线LAN,ARP协议(查找MAC地址) | 负责设备之间的数据 |
物理层 | 双绞线,wifi电磁波(无线)集线器,网卡 | 发送0,1光电信号,负责比特流在节点间的传输 |
2.TCP的三次握手与四次挥手
开始的时间:传输层
2.1TCP的传输如图所示:
2.2 SYN与ACK的作用
在TCP协议中,SYN和ACK是两个标志位(Flag)用于标识TCP数据包的类型。SYN是**Synchronize(同步)的缩写,ACK是Acknowledgement(确认)**的缩写。
具体来说,当一台计算机向另一台计算机建立TCP连接时,它会发送一个SYN数据包,用来请求建立连接。而当接收到这个SYN数据包后,另一台计算机会回复一个SYN+ACK数据包,表示已经收到了请求,并准备好建立连接。最后,第一台计算机会回复一个ACK数据包,表示已经确认了连接。
SYN和ACK标志位在TCP三次握手的过程中起着重要作用,具体来说:
- SYN标志位用于标识TCP连接建立请求,通常由客户端发起,表示客户端要向服务器发起连接请求。
- ACK标志位用于标识TCP数据包的确认,表示数据包已经成功传输。在TCP三次握手中,服务器在回复SYN+ACK请求时,会将ACK标志位设置为1,表示已经确认了客户端的请求。
总之,SYN和ACK标志位是TCP协议中用于标识数据包类型的重要标志位,它们在TCP三次握手过程中发挥着关键作用,确保TCP连接的可靠性和稳定性。
2.3 seq的作用
在TCP协议中,序列号(Sequence Number,简称seq)是用于标识TCP数据包中数据的序号。每个TCP数据包都会包含一个序列号,用来标识传输的数据在整个TCP连接中的位置。
序列号主要有两个作用:
- **确定数据包的顺序:**序列号用于标识TCP数据包中传输数据的顺序。在TCP连接建立后,每个数据包都会按照序列号顺序进行传输,确保数据能够正确到达接收方。
- **确定数据包的唯一性:**序列号也用于标识TCP数据包的唯一性。每个TCP数据包的序列号都是唯一的,确保每个数据包都能够正确地被接收方识别。
在TCP连接建立时,客户端和服务器都会生成一个随机的初始序列号(ISN),用于标识数据包的序列号。在建立连接时,客户端和服务器会相互发送带有自己ISN的SYN数据包,以此来确认对方的序列号。
总之,序列号是TCP协议中的一个重要概念,用于标识TCP数据包中传输数据的序号,保证数据包按照正确的顺序进行传输,并保证每个数据包的唯一性。
2.4 TCP的三次握手
2.4.1 三次握手的作用
建立TCP连接后传递数据
2.4.2 具体步骤
TCP三次握手是建立TCP连接的过程,其主要目的是确保客户端和服务器之间的通信能够正常进行。这个过程涉及到三个主要步骤:
- 客户端向服务器发送一个SYN请求(SYN=1),表示客户端要向服务器发起连接请求。客户端首先会随机生成一个初始序列号(ISN),用于标识客户端发送的数据包。
- 服务器接收到客户端的SYN请求后,回复一个SYN+ACK请求(SYN=1,ACK=1),表示服务器已经接收到了客户端的请求,并准备好建立连接。服务器在回复SYN+ACK请求时,会将自己的初始序列号(ISN)加1作为确认号(ACK),同时也会生成一个自己的随机序列号(ISN)作为标识。
- 客户端接收到服务器的SYN+ACK请求后,回复一个ACK请求(SYN=0,ACK=1),表示客户端已经接收到了服务器的回复,连接已经建立。在ACK请求中,客户端将确认号设置为服务器发送的序列号加1,将序列号设置为客户端初始序列号加1。
这个过程可以用以下步骤概括:
- 客户端发送SYN请求,包含客户端的初始序列号。
- 服务器回复SYN+ACK请求,包含服务器的初始序列号和确认号。
- 客户端回复ACK请求,确认连接建立,包含客户端和服务器的序列号和确认号。
在三次握手过程中,如果任何一方没有收到另一方的请求,就会超时并重新发送请求,直到连接建立成功或者放弃连接。这个过程可以确保客户端和服务器之间的通信是可靠和稳定的。
在TCP三次握手过程中,最后的ACK请求中,SYN标志位通常被设置为0,而不是1。这是因为SYN标志位在握手过程中的作用仅限于建立连接阶段,一旦连接已经建立,SYN标志位就不再有意义。在建立连接后,TCP通信的双方会开始正式的数据传输,这时ACK标志位变得更为重要,因为它表示双方已经确认了彼此的数据。
在TCP三次握手的最后一步中,客户端向服务器发送的ACK请求中,SYN标志位被设置为0,是为了告诉服务器,客户端不再需要SYN标志位了,连接已经建立成功,可以开始数据传输了。此时ACK标志位被设置为1,表示客户端已经接收到服务器的SYN+ACK请求,并已经确认了连接建立成功。
因此,SYN标志位在TCP三次握手的过程中是用来建立连接的,而在连接建立后,SYN标志位就没有作用了。而ACK标志位则是在整个TCP通信过程中都非常重要的标志位,用来确认双方的数据是否已经正确传输。
最开始的时候客户端和服务器都是处于CLOSED状态。主动打开连接的为客户端,被动打开连接的是服务器。
2.5.TCP的四次挥手
2.5.1四次挥手的作用
数据传送完毕,断开连接时就需要进行TCP的四次挥手
2.5.2具体步骤
- 第一次挥手(FIN):关闭方向被关闭的一方(例如客户端)发送一个FIN数据包给对方(例如服务器),表示它已经没有数据要发送给对方了,但是仍然可以接收数据。
- 第二次挥手(ACK):对方(例如服务器)收到了关闭方发送的FIN数据包,向关闭方发送一个ACK数据包作为响应,表示已经接收到了关闭方的请求。
- 第三次挥手(FIN):对方(例如服务器)向关闭方发送一个FIN数据包,表示对方已经没有数据要发送给关闭方了。
- 第四次挥手(ACK):关闭方(例如客户端)收到了对方发送的FIN数据包,向对方发送一个ACK数据包作为响应,表示已经接收到了对方的请求。
3.注意
3.1为什么是三次握手
原因主要有两个:
1、主要原因是为了防止历史连接
三次握手时,在网络拥堵等情况下,第一次握手的SYN包迟迟没能发送到服务端,那么客户端会连续发送多次 SYN 建立连接的报文,那么就可能出现一个「后发送SYN 报文」比「早发送的 SYN 报文」 早到达了服务端;
那么此时服务端就会回一个 SYN + ACK 报文给客户端;
如果是两次握手连接,就不能判断当前连接是否是历史连接,导致错误。
三次握手时,客户端收到后可以根据自身的上下文,判断这是一个历史连接(序列号过期或超时),那么客户端就会发送 RST 报文给服务端,中止这一次连接。
2、三次握手可以避免资源浪费
如果只有「两次握手」,当客户端的 SYN 请求连接在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN ,
如果是三次握手,第三次握手时服务器可以得到客户端的ack,知道连接已成功建立。
如果没有第三次握手,服务器不清楚客户端是否收到了自己发送的建立连接的 ACK 确认信号,所以每收到一个 SYN 就只能先主动建立一个连接,如果客户端的 SYN 阻塞了,重复发送多次 SYN 报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。
3.2为什么是四次挥手
为什么建立连接是三次握手,关闭连接确是四次挥手呢?
关闭连接时无法优化为三次,原因如下:
服务器收到对方的FIN报文时,很可能还有数据没发完,需要等到数据发送完毕之后才向客户端发送FIN报文,但是又不能让客户端等太久,就先发ACK告诉客户端我收到了你的FIN释放连接请求,客户端收到ACK之后便不会重复发送断开连接的请求。
等到服务器数据传输完毕后,才会发FIN释放连接报文。
另外,如果服务端确定没有数据需要发给客户端,那么当然是可以把 FIN 和 ACK 合并成一个包,四次挥手的过程就成了三次。
3.3为什么三次握手中server给client传递的ack = seq+1
在TCP三次握手中,服务器端在收到客户端发送的SYN包后,需要确认客户端发送的序列号seq,并且也需要向客户端发送一个ACK数据包以确认收到了客户端发送的SYN包。因此,服务器端向客户端发送的ACK数据包中的确认号ack需要设置为客户端发送的SYN包的序列号seq加1,表示服务器端已经成功接收到了客户端发送的SYN包,并且下一个数据包应该从seq+1开始发送。
这种设置ACK的确认号ack等于seq+1的方式,可以保证客户端能够收到服务器端的确认信息,并且也可以避免服务器端接收到重复的SYN包时重复建立连接
(在ACK包中确认收到客户端发送的SYN包的序列号seq,同时在ACK包中将确认号ack设置为seq+1。这样,在客户端重复发送相同的SYN包时,服务器端会忽略掉这些重复的SYN包,因为在之前已经确认过这些SYN包,并且已经返回过相应的ACK包。这就可以避免重复建立连接的问题。)
同时,这种设置还可以防止一些恶意攻击,例如SYN洪泛攻击,防止攻击者利用TCP的设计漏洞来占用服务器资源或者造成拒绝服务等问题。
因此,在TCP三次握手中,服务器端向客户端发送的ACK数据包中的确认号ack等于seq+1,是一种合理且有效的设置方式。