计算机网络——TCP三次、四次握手详解

本文详细解析了TCP连接建立与释放的过程,包括三次握手建立连接的原因及四次挥手断开连接的必要性。解释了为何连接建立时只需要三次握手,而断开连接时却需要四次挥手。

三次握手:建立TCP连接


连接建立过程:

  B的TCP服务器进程先创建传输控制块TCB(存储了每一个连接中的一些重要信息,如:TCP连接表,到发送和接收缓存的指针,到重传队列的指针,当前的发送和接收序号,等),准备接受客户进程的连接请求。然后服务器进程就处于LISTEN(收听)状态,等待客户的连接请求。如有,即作出相应。
  A的TCP客户进程也是首先创建传输控制模块TCB,然后向B发出连接请求报文段,这时首部中的同步为SYN=1,同时选择一个初始序号seq=x。TCP规定,SYN报文段(即SYN=1的报文段)不能携带数据,但要消耗掉一个序号。这时,TCP客户进程进入SYN-SENT(同步已发送)状态。
  B收到连接请求报文段后,如同意建立连接,则向A发送确认。在确认报文段中应把SYN位和ACK位都置1,确认号是ack=x+1,同时也为自己选择一个初始序号seq=y。注意。这个报文段也不能携带数据,但同样要消耗掉一个序号。这时TCP服务器进程进入SYN-RCVD(同步收到)状态。
  TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的ACK置1,确认号ack=y+1,而自己的序号seq=x+1。这时,TCP连接已经建立,A进入ESTABLISHED(已连接状态)。
  当B收到A的确认后,也进入ESTABLISHED状态。
  以上便是三次握手的流程。

问题:

  1.为什么不可以是两次握手?为什么A还要发送一次确认?

  答:主要是为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误。

  比如说这种异常情况:A发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以致延误到连接释放以后的某个时间才到达B。本来这是一个早已失效的报文段。但B收到此失效的连接请求报文段后,就误以为是A又发出一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出确认,新的连接就建立了。

  由于现在A并没有发出建立连接的请求,因此不会理财B的确认,也不会向B发送数据。但B却以为新的连接已经建立了,并一直等待A发来数据。B的许多资源就这样被浪费。

四次握手:TCP的连接释放


连接释放过程:

  过程高端、复杂,复制别人的(=。=):

  中断连接端可以是Client端,也可以是Server端。

  假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了

问题:

  1.为什么建立连接时是三次握手,而断开时需要四次握手?

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

转载于:https://www.cnblogs.com/zhengbin/p/5608049.html

### TCP 连接建立与断开过程 #### 三次握手过程详解 TCP 使用三次握手来建立可靠的连接。具体过程如下: 当客户端希望与服务器建立通信时,会发送一个带有 SYN 标志的数据包给服务器,此时该数据包中的序列号设为 `x`。 服务器收到这个请求后,如果同意建立连接,则向客户端回送一个 ACK 报文作为应答,并设置确认序号为 `x+1` 同时也携带自己的初始序列号 `y` 和 SYN 标记[^1]。 最后一步是由客户端再次回应服务器一个 ACK 数据段,其中包含对服务器之前发送过来的序列号加一后的值即 `y+1` 来表示已经成功接收到了来自对方的信息并准备就绪可以开始传输实际数据了[^2]。 ```python # 客户端发起SYN请求 client.send(SYN, seq=x) # 服务端响应SYN/ACK server.receive(SYN, seq=x) server.send(ACK, ack=x + 1, seq=y, SYN=True) # 客户端完成第三次握手 client.receive(ACK, ack=x + 1, seq=y) client.send(ACK, ack=y + 1) ``` #### 四次挥手流程 对于终止一条已有的TCP连接来说,通常采用的是四步挥手的方式来进行操作。以下是具体的步骤描述: 一方(假设为客户方)先主动关闭连接并向另一方发送 FIN 控制位置位的数据报;接着等待被通知的一侧回复一个 ACK 应答信号以表明它收到了结束指示并且不再期待更多来自原方向上的新信息流[^3]。 随后被动关闭的那一边也会发出自己想要中断的意思表达也就是第二个 FIN ,与此同时还要附带有一个新的序列编号用于跟踪这条消息的状态变化情况;最终由最初提出切断提议者给出最后一个确认答复——第三个也是第四个 ACK 消息,以此正式宣告整个双向通讯链路彻底解除关系。 ```python # 主动关闭方发送FIN active_side.send(FIN, seq=a) # 被动关闭方返回ACK passive_side.receive(FIN, seq=a) passive_side.send(ACK, ack=a + 1) # 被动关闭方发送FIN passive_side.send(FIN, seq=b) # 主动关闭方返回ACK active_side.receive(FIN, seq=b) active_side.send(ACK, ack=b + 1) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值