TCP 三次握手
三次握手流程图
- 序列号seq:占4个字节,用来标记数据段的顺序,TCP 把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号 seq 就是这个报文段中的第一个字节的数据编号;
- 确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号 +1 即为确认号;
- 确认ACK:占1位,仅当 ACK = 1 时,确认号字段才有效。ACK = 0 时,确认号无效;
- 同步SYN:连接建立时用于同步序号。当 SYN = 1,ACK = 0 时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得 SYN = 1,ACK = 1。因此,SYN = 1表示这是一个连接请求,或连接接受报文。SYN 这个标志位只有在 TCP 建产连接时才会被置1,握手完成后 SYN 标志位被置0;
- 终止FIN:用来释放一个连接。FIN = 1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接。
ACK、SYN 和 FIN 这些大写的单词表示标志位,其值要么是1,要么是0;ack、seq 小写的单词表示序号。
三次握手的过程
- 第一次握手:建立连接。客户端发送连接请求报文段给服务器,客户端进入 SYN_SEND 状态,等待服务器的确认;
- 第二次握手:服务器收到 SYN 报文段,并发送 ACK + SYN 报文段给客户端,此时服务器进入 SYN_RECV 状态;
- 第三次握手:客户端收到服务器的 SYN+ACK 报文段,并向服务器发送报文段 ACK + SYN,这个报文段发送完毕以后,客户端和服务器端都进入 ESTABLISHED 状态,完成TCP三次握手。
为什么需要三次握手
主要是为了防止已失效的连接请求报文段突然又传到了服务器,因而产生错误。三次握手能保证建立安全可靠的连接,第一次握手由客户端发起,第二次握手服务端做出响应,此时对客户端来说,两次握手已经足够了,因为客户端既能向服务端发送消息又能收到服务端的响应,但是对服务端来说是不够的,因为它只收到来自客户端的请求信息,并不知道客户端有没有收到它的响应信息。所以,必须至少有三次握手,才能建立可靠安全的 TCP 连接。
TCP 四次挥手
四次挥手流程图
四次挥手的过程
- 第一次挥手:客户端的主动关闭 TCP 连接。客户端向服务器发送请求断开连接字段。客户端进入 FIN-WAIT-1 (终止等待1) 状态,等待服务器的确认;
- 第二次挥手:服务器收到连接释放报文段后即发出确认。然后服务器就进入 CLOSEWAIT(关闭等待)状态。这时的 TCP 连接处于半关闭(Half-close)状态,客户端到服务器这个方向的连接已经关闭了,客户端已经没有数据要发送了,但服务器若发送数据,客户端仍要接收。也就是说,服务器到 客户端这个方向的连接并未关闭,这个状态可能会持续一段时间。客户端收到来自服务器的确认后,就进入FIN-WAIT-2 (终止等待2) 状态,等待服务器发出的连接释放报文段;
- 第三次挥手:如果服务器已经没有要向客户端发送的数据,就通知 TCP 释放连接。服务器还必须重复上次已发送过的确认号ack。这时服务器就进入 LAST-ACK (最后确认) 状态,等待客户端的确认。
- 第四次挥手:客户端在收到服务器的连接释放报文段后,必须对此发出确认。然后进入到 TIME-WAIT(时间等待) 状态。
为什么需要四次挥手
TCP 断开连接同样是由客户端发起的,服务端收到客户端的断开请求之后,此时的服务端并不一定做好断开连接的准备,因为可能还有数据没有传送完成,服务端能做的只是做出确认断开连接的响应。等到服务端准备好断开连接了,就向客户端发送断开连接的信号,客户端收到信号之后做出回应,因此有四次挥手。