前端小白的TCP学习笔记

236 阅读6分钟

TCP是什么?

TCP即传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议,旨在适应支持多网络应用的分 层协议层次结构。

TCP的特点

  • TCP 连接只能是点对点(一对一)的。
  • TCP是面向连接的运输层协议,它允许两个应用进程之间建立一条传输连接,应用进程通过传输连接可以实现顺序、无差错、不重复和无报文丢失的流传输。在一次进程数据交互结束时,释放传输连接。
  • TCP提供可靠交付的服务,保证每次数据按序、按时、不丢数据,顺利的交付给对方。
  • TCP提供全双工通信,可以同时进行双向数据传输,但是由于TCP连接只能是点对点(一对一)的,所以不支持组播、广播。
  • TCP 是面向字节流的协议。

三次握手

TCP的三次握手是建立连接的过程。在建立三次握手之前,主动打开连接的客户端先结束CLOSED状态,并且被动打 开的服务器端也停止CLOSED状态,变为LISTEN状态,而后进入三次握手阶段。

三次握手过程就像两个好朋友打招呼的过程,首先朋友A(客户端)向朋友B(服务器端)用一个微笑来传递打招呼的请求,B在收到A的打招呼请求后,先确认了是否是自己的朋友在向自己微笑,确认完成后便也向A回了一个微笑应答,A收到B的微笑后也需要确认一下是否是B对自己微笑,确认完成后,向B表示已经收到了B的微笑,接下来可以进行交流。在整个过程中,A和B都需要完成微笑和确认对方的两个动作,B将微笑和确认两个动作在同一阶段完成,这也就是为什么是三次握手,而不是四次握手。

824490-1590076700.jpg

1.第一次握手

第一次握手就像A向B微笑,希望B也能向自己微笑,建立联系的过程。客户端向服务器端发送一个SYN包,此时SYN报文就像A传递的微笑,其中包括SYN标志位为1,表示请求建立连接;序号seq=x(一般是随机数)。随后客户端进入SYN-SENT状态。

2. 第二次握手

第二次握手就像是B在收到A的打招呼请求后,先确认了是否是自己的朋友在向自己微笑,确认完成后便也向A回了一个微笑应答。服务器端成功接收并确认客户端发送来的SYN报文后,结束LISTEN状态。再向客户端发送ACK确认包,其中SYN、ACK标志位都为1,还包括确认序号ack为接收到的序号seq加1(即ack=x+1),和序号seq=y(一般是随机数)。服务器端在将这些数据发送给客户端以确认连接请求后,进入SYN-RCVD状态。

3. 第三次握手

第三次握手就像A收到B的微笑后,确认是B的微笑的过程。客户端在接收并确认服务器端发送来的数据包中的ACK标志位为1,ack序号为x+1后,结束SYN-SENT状态,再向服务器端发送确认连接请求,其中发送的数据包包括ACK标志位为1,序号为 Seq = x + 1,表示收到服务器端的确认号 Ack,并将其值作为自己的序号值;确认号为 ack= y + 1,表示收到服务器端序号seq,并将其值加1作为自己的确认号 ack的值。随后客户端进入ESTABLISHED状态。当服务器端收到来自客户端确认收到服务器数据的报文后,得知从服务器到客户端的数据传输是正常的,从而结束 SYN-RECV 状态,也进入ESTABLISHED状态,从而完成三次握手。

四次挥手

四次挥手即TCP断开连接,需要客户端和服务器端都发送FIN报文终止连接。在断开连接之前客户端和服务器都处于ESTABLISHED状态,双方都可以主动断开连接,以客户端主动断开连接为优。

u=2099872463,154045557&fm=253&fmt=auto&app=138&f=PNG.webp

第一次挥手

客户端主动提出断开连接,向服务器端发送FIN报文(FIN标志位为1),序列号seq=u,状态转为FIN-WAIT1。

第二次挥手

服务器端收到FIN报文后,就向客户端发送ACK应答报文,以客户端的FIN报文的序列号 seq+1 作为ACK应答报文段的确认序列号ack = seq+1 = u + 1,服务器进入CLOSE_WAIT(等待关闭)状态。

第三次挥手

服务器端也打算断开连接,向客户端发送连接释放(FIN)报文段(FIN=1,ACK=1,序列号seq=m,确认序列号ack=u+1),之后服务器进入LASK_ACK状态,等待客户端的确认。

第四次挥手

客户端收到来自服务器的连接释放(FIN)报文段后,会向服务器发送一个ACK应答报文段,以连接释放(FIN)报文段的确认序号 ack 作为ACK应答报文段的序列号 seq,以连接释放(FIN)报文段的序列号 seq+1作为确认序号ack。之后客户端进入TIME_WAIT(时间等待)状态,服务器收到ACK应答报文段后,服务器就进入CLOSE(关闭)状态,到此服务器的连接已经完成关闭。客户端处于TIME_WAIT状态时,此时的TCP还未释放掉,需要等待2MSL后,客户端才进入CLOSE状态。

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

由于 TCP 的半关闭(half-close)特性,TCP 提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。

任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。 通俗的来说,两次握手就可以释放一端到另一端的 TCP 连接,完全释放连接一共需要四次握手。

举个例子:A 和 B 打电话,通话即将结束后,A 说 “我没啥要说的了”,B 回答 “我知道了”,于是 A 向 B 的连接释放了。但是 B 可能还会有要说的话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,于是 B 向 A 的连接释放了,这样整个通话就结束了。