TCP的全双工通信

TCP提供的全双工是可以一端读另一端写的,如何实现的,实际上服务端到客户端是一条通道,同时客户端到服务端又是另一条通道,首先明白这一点,然后再来看下面。

三次握手

回顾三次握手

三次握手建立连接,客户端在创建socket网络套接字后,会通过三次握手这个过程来进行连接:

  1. 调用connect向服务端发起连接请求,发送了一个SYN,阻塞等待服务端回复(第一次握手)
  2. 服务端收到客户端发送的SYN,为了让客户端知道他这准备好了,于是回了一个ACK告诉客户端我准备好了,并且发了一个SYN问客户端准备好没(第二次握手)
  3. 客户端收到服务端回复的ACK,进入ESTABLELISHED状态,准备就绪,并回了一个ACK给服务端说我也准备好了,服务端收到ACK确认了对方状态,于是也进入ESTABLELISHED状态,连接建立(第三次握手)

为什么是三次握手而不是两次或四次?

三次肯定是有道理的,存在即合理,三次可以让双方都确定连接到对方后能收到对方的回复,双方都准备好了。

如果是两次,那么看下面过程,仔细对比上面的三次握手:

  1. 客户端调用connect,发送了一个SYN,然后服务端接收这个SYN(第一次握手)
  2. 服务端接收之后就会返回一个ACK,那么客户端就进入ESTABLELISHED状态(第二次握手)

这其中有一个问题,那就是服务端并不知道,如果服务端发送一个消息,客户端会不会回复,如果客户端不回复,那么这个连接就是不可靠的,我服务端给你发数据,你居然不回我你收到没,那服务端怎么可能知道客户端是收到还是没收到?????

也就是说当我两次握手的时候,首先,客户端知道他到服务端的那条通道已经通了,但是服务端到客户端的那条通道,服务端不知道通没通,所以服务端也要回一个SYN,而不是光返回一个ACK,由客户端回复的ACK确认服务端到客户端的通道是否是通的。

所以要一开始就需要第二次握手服务端在返回ACK时,同时返回一个SYN,来确定客户端会回我服务端的消息,那我才能确定连接成功了。

至于四次,我三次就能建立连接成功了,还来一次握手,要是哪天客户端来个第四次握手,那我估计服务端要骂客户端傻逼了。。。。
为什么TCP握手是三次挥手是四次?

四次挥手

回顾四次挥手

如果客户端没有请求了,主动关闭,那么便会调用close关闭连接

  1. 客户端调用close,发送了一个FIN包给服务端,告诉服务端要断开了(第一次挥手)
  2. 服务端收到FIN后,告诉客户端我知道了要断开连接了,于是发了一个ACK给客户端,同时recv(或read)会返回0(第二次挥手)
  3. recv和read返回0,于是服务端也调用了close关闭套接字问价,并给客户端发了一个FIN包,告诉客户端我也要关了(第三次挥手)
  4. 客户端收到FIN,回了一个ACK,说我知道了,断了吧(第四次挥手)

为什么是四次挥手,不是三次或五次?

首先,主动关闭方是会先发送FIN包给被动关闭方的,这个主动关闭方可能是客户端也可能是服务端,只不过大部分的情况都是客户端主动关闭。

那为啥是四次???我们以客户端主动关闭举例

首先我们已经知道了TCP的连接是全双工的,有两条通道,这两条通道,主动关闭方发送FIN,告诉被动方我要断了,被动方回一个ACK,主动方收到后就断开了,那么客户端到服务端这条通道就算断开了。

但是被动方也就是服务端仍然可以给主动方发消息的,也就是说服务端到客户端那条通道没有断开,等到服务端这一端数据发完了,这条通道也就需要关闭了,所以服务端也发了一个FIN包,告诉客户端我工作做完了,我也要关了,等到服务端收到客户端的ACK或者超出等待时间那么就断开连接。

三次的话如果类比三次握手,在第二次挥手的时候直接发FIN + ACK明显不合理,因为被动方可能没有数据发送完,你这么关太草率了,所以需要四次,至于五次,四次就能断开了,还来五次。。。多此一举。。
为什么TCP握手是三次挥手是四次?

相关文章:

  • 2021-06-01
  • 2021-10-26
  • 2021-05-15
  • 2022-01-10
  • 2021-06-25
  • 2021-05-16
  • 2021-09-20
猜你喜欢
  • 2021-07-25
  • 2021-08-01
  • 2021-04-21
  • 2021-07-23
  • 2021-05-28
  • 2019-01-23
相关资源
相似解决方案