一、TCP协议
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。
二、TCP协议中的标识位(位码)
- SYN (synchronous建立联机)
- ACK (acknowledgement 确认)
- PSH (push传送)
- FIN (finish结束)
- RST (reset重置)
- URG (urgent紧急)
- Sequence number (顺序号码)
- Acknowledge number (确认号码)
三、TCP三次握手
- 第一次握手:客户端发送位码为syn=1,随机产生seq number= X 的数据包到服务器,服务器由客户端发送的SYN=1知道,客户端要求建立联机;
- 第二次握手:服务器收到请求后要确认联机信息,向客户端发送ack number=(客户端的seq+1),syn=1,ack=1,随机产生seq=Y的包;
- 第三次握手:客户端收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,客户端会再发送ack number=(主机B的seq+1),ack=1,服务器收到后确认收到的seq值与发送给客户端的seq+1是否相等和ack是否为1来判断连接是否建立成功。
四、为什么是三次握手,两次握手不行吗?
- 第一次握手:客户端发送网络包,服务端收到了。
- 服务端能得出结论:客户端的发送能力是正常的,但服务端不能确认客户端的接收能力是否正常。
- 客户端得出结论:无。
- 第二次握手:服务端发包,客户端收到了。
- 客户端能得出结论:服务端的接收、发送能力都是正常的。(客户端 ✅)
- 服务端仍然不能确认客户端的接收能力是否正常。(因此需要进行第三次握手)
- 第三次握手:客户端发包,服务端收到了。
- 服务端能得出结论:客户端的接收、发送能力都是正常的。(服务端 ✅)
因此,需要三次握手才能确认双方的接收与发送能力是否正常。
五、三次握手过程中可以携带数据吗?
其实第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据
为什么这样呢?大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。
也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。