TCP/I三次握手四次挥手

 

最初两端都是CLOSED状态,A主动打开连接,而B被控打开连接
A、B关闭状态CLOSED----B收听状态LISTEN----A同步已发送状态SYN-SEND----B同步收到状态SYN-RCVD----A、B连接已建立状态ESTABLISHED

B的TCP服务器进程先创建控制块TCB,准备接受客户进程的连接请求。然后服务器进入LISTEN状态,等待客户端的连接请求。
第一次握手:A的TCP客户进进程也是首先创建传输控制块TCB,然后向B发出连接,SYN=1(不允许携带数据,会消耗一个序号),seq=x(x是随机生成的),A进入SYN_SEND状态
第二次握手:B收到请求报文后,回送报文,SYN=1,ACK=1(可以携带数据,不携带数据不会消耗序号),seq=y(y是随机生成的),ack=x+1,B进入SYN_RCVD状态
第三次握手:A收到B的确认后,回送报文,ACK=1,seq=x+1,ack=y+1,A进入ESTABLISHED。当B收到A的确认后,也进入ESTABLISHED状态

为什么A要发送一次确认呢?可以二次握手吗?
主要是为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误。如A发出连接请求。如A发出连接请求,但是连接请求报文丢失服务器未收到。于是A再重传一次连接请求,后来收到确认,建立了连接。数据传输完毕后,就释放了连接,A共发出了两次请求报文段,其中一个丢失,第二个到达B,但是第一个丢失的报文段只是在某些网络节点长时间滞留了,延误到释放连接后的某个时间才到达B,此时B误认为A又发出一次新的连接请求,于是就向A发出确认报文段,同意建立连接,如果不采用三次握手,只要B发出确认,就建立新的连接了,如果此时A不理睬B的确认且不发送数据,B就会一直等待A发送数据,浪费资源。

Server端易收到SYN攻击?
服务器端的资源分配是在第二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪水攻击,SYN攻击就客户端在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待客户端确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列慢而被丢弃,从而引起网络拥塞甚至系统瘫痪。
防范SYN攻击措施:降低主机的等待时间使主机尽快的释放半连接的占用,短时间收到某IP的重复SYN则丢弃后续请求。

期初A和B处于ESTABLISHED状态----A发出连接释放报文段并处于FIN-WAIT-1状态----B发出确认报文段进入CLOSE-WAIT状态----A收到确认后,进入FIN-WAIT-2状态并等待B的连接释放报文----B没有数据要向A发送的数据,B发出连接释放报文段切进入LAST-ACK状态----A发出确认报文段进入TIME-WAIT状态----B收到确认报文段后进入CLOSED状态----A经过等待计时器时间2MSL后,进入CLOSED状态。

A的应用进程先向TCP发送释放报文,FIN=1,seq=u,并停止再发送数据,主动关闭TCP连接,进入FIN-WAIT-1(终止等待1)状态,等待B的确认

B收到连接释放报文段后即发出确认报文段,ACK=1,seq=v,ack=u+1,B进入CLOSE-WAIT(关闭状态)状态,此时的TCP处于半关闭状态,A到B的连接释放

A收到B的确认后,进入FIN-WAIT-2(终止等待2)状态,等待B发出连接释放报文段

B没有数据向A发送了,B发出连接释放报文段FIN=1,ACK=1,seq=w,ack=u+1,B进入LAST_ACK(最后确认)状态,等待A的确认

A收到B的连接释放报文段后,回送确认报文 ACK=1,seq=u+1,ack=w+1,A进入TIME-WAIT(时间等待)状态。此时TCP连接为释放掉,需要经过时间等待计时器设置的时间2MSL后,A才进入CLOSED状态

为什么A在TIME-WAIT状态必须等待2MSL的时间?
MSL最大报文段寿命Maximum Segment Lifetime, MSL=2
1、保证A发送的最后一个ACK报文段能够到达B
2、防止“已失效的连接请求报文段”出现在本连接中
1)这个ACK报文段可能丢失,使得处于LAST-ACK状态的B收不到已发送的FIN+ACK报文段的确认,B超时重传FIN+ACK报文段,而A能在2MSL时间内收到这个重换的FIN+ACK报文段,接着A重传一次确认,重新启动2MSL计时器,最后A和B都进入到CLOSED状态,若A在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到B重传的FIN+ACK报文段,所以不会再发送一次确认报文,则B无法正常进入到CLOSED状态
2)A在发送完最后一个ACK报文段后,在经过2MSL,就可以使本连接持续的时间内所产生的所有报文都从网路中消失,使下一个新的连接中不会出现这种就旧的连接请求报文

为什么连接的时候是三次握手,关闭的时候却是四次握手?
因为当Server段收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。所以需要四次捂手

为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSED状态?
虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSED状态了,但是我们必须假想网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

 

### TCP/IP 三次握手四次挥手的详细过程 #### 一、TCP/IP 三次握手的过程 TCP 协议通过三次握手建立可靠的连接。以下是其具体流程: 1. **第一次握手** 客户端向服务器发起请求,发送一个 SYN 数据包(同步序列号),表示希望与服务器建立连接并携带初始序列号 m[^1]。 2. **第二次握手** 服务器接收到客户端的 SYN 请求后,会回复一个包含自己 SYN 序列号 n 和对客户端 ACK(m+1) 的确认包给客户端。这表明服务器已准备好接受来自客户端的数据流,并将自身的序列号告知客户端。 3. **第三次握手** 客户端收到服务器返回的 SYN(n) 和 ACK(m+1),此时客户端进入 ESTABLISHED 状态。随后,客户端再次向服务器发送 ACK(n+1) 来确认收到了服务器的 SYN 包,从而完成整个三次握手过程,双方正式建立起可靠连接。 ```python # Python模拟三次握手逻辑 class TCPSession: def __init__(self): self.client_seq = 0 self.server_seq = 0 def client_send_syn(self): # 发送SYN包 return {"type": "SYN", "seq": self.client_seq} def server_respond_syn_ack(self, seq): # 接收SYN并响应SYN/ACK ack_num = seq + 1 syn_num = self.server_seq self.server_seq += 1 return {"type": ["SYN", "ACK"], "ack": ack_num, "syn": syn_num} def client_confirm_ack(self, syn, ack): # 确认服务器的SYN/ACK if ack == (self.client_seq + 1): self.client_seq += 1 return {"type": "ACK", "ack": syn + 1} ``` --- #### 二、TCP/IP 四次挥手的过程 当通信结束时,需要释放资源并通过四次挥手断开连接。以下是具体的步骤: 1. **第一次挥手** 主动关闭的一方(通常是客户端)发送 FIN 数据包通知对方要终止该方向上的数据传输。此操作意味着“我已经没有更多数据要发送了”。FIN 中包含了当前序列号 p[^2]。 2. **第二次挥手** 被动关闭一方(通常为服务器)接收到 FIN 后,不会立刻关闭连接而是先进入 CLOSE_WAIT 状态。它会回应一个 ACK(p+1) 表明已经接受了对方停止发送的要求,但仍然可以继续接收剩余未处理完毕的数据[^2]。 3. **第三次挥手** 当被动关闭方也完成了所有的数据传送之后,则同样发出自己的 FIN(q),告诉另一侧现在也可以安全地切断反方向上的链路了[^2]。 4. **第四次挥手** 最终,主动关闭方回传最后一个 ACK(q+1),至此两台设备均处于 TIME_WAIT 或 CLOSED 状态,标志着完整的双向链接被彻底拆除[^2]。 --- ### 总结 - 三次握手的核心在于确保两端都能正确初始化各自的序列号以及验证彼此的存在。 - 四次挥手中的额外两次是因为即使某一边想要结束对话,另一边仍有可能还有尚未送达的信息等待传递出去的缘故。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值