TCP
TCP协议由互联网工程任务组(Internet Engineering Task Force, IETF)维护。IETF官网地址为https://www.ietf.org/。TCP协议具体细节定义在RFC文档中。其中最重要的RFC 793,它定义了TCP协议的具体规则。
Key Words
- SYN报文 SYN(synchronize)报文是TCP报文的一种。了解SYN报文需要了解TCP报文结构中的控制位和序列号。控制位包含一些控制信息,如SYN、ACK、FIN等。在SYN报文中,控制位的SYN位被设置为1,表示这是一个连接请求报文。序列号字段包含的是这个连接的初始序列号。
- ACK报文 ACK(acknowledgement)报文是TCP中用于确认接收数据的一种报文类型。当主机接收到一个TCP数据包后,需要发送ACK报文给发送端,以确认已成功接收数据。这个ACK报文包含一个确认号。 ACk报文是TCP可靠性机制的一部分。通过使用ACK报文,TCP可以确保所有发送数据被成功接收。如果发送端没有在一定时间内接收到ACK报文,它会重新发送数据,直到接收到ACK报文为止。 确认号 在TCP中,确认号是一个重要的字段,它用于确认接收到的数据。 当TCP报文从发送端到接收端时,接收端会发送一个ACK报文回发送端,以确认已经接收到数据。这个ACK报文中的确认号字段就是接收端期望接收的下一个字节的序号。 例如:如果发送端发送了一个序列号为100的数据段,那么接收端在确认接收到这个数据段后,会发送一个确认号为101的ACK报文。表示接收端已经接收到序列号为100的数据段,并期望收到序列号为101的数据段。 注意:ACK确认号用于确保所有发送的数据能够被成功接收。ACK确认号本身是不能阻止中间人攻击的,因为TCP协议本身是不提供加密的。如果攻击者能够截取TCP数据包,那就能修改包括ACK确认号在内的数据。TCP连接的加密依赖于其他加密技术,如SSL/TLS。
- FIN报文 FIN(finish)报文用于表示发送方已经完成了数据传输任务,希望断开连接。需要注意的是,发送FIN包不代表立刻断开连接,收到FIN包的一方会在所有数据都接收完成后,回复ACK包。只有当双方都发送并确认FIN包后,连接才会正在断开。
- 全双工 全双工是指通讯系统中的两个设备具有同时接收和发送数据的功能。全双工模式下,数据在两个方向上同时传输,互不干扰。电话通话就是典型的全双工通信。在计算机网络中,TCP协议就是全双工的,这是理解四次挥手的关键。
三次握手
- 客户端向服务器端发送SYN报文,表示请求连接。这个SYN报文包含一个随机的初始序列号。
- 服务器端接收到客户端发送的SYN报文后,向客户端发送ACK报文以确定接收来自客户端SYN报文,同时发送SYN报文。这个SYN报文包含自身的初始序列号。
- 客户端接收到SYN-ACK报文后,发送ACK报文确认接收,标志成功建立连接。 为什么是三次握手而不是两次握手或者四次握手 请求TCP连接时的握手是为了确保双方都具备发送和正确接收的能力。 两次不靠谱(浪费资源),四次没必要。
四次挥手
- FIN:需要断开连接的一方(设为A)完成数据传输后,它向另一方(设为B)发送FIN包,表示“A数据发送完毕,请求断开连接”。
- ACK:B接收到A的FIN包后,并不立刻断开连接,而是向A发送ACK包,表示“已经接收到请求,请等待B完成数据发送”。
- FIN:B完成数据传输后,向A发送FIN包,表示“B数据已经发送完毕,可以断开连接”。
- ACK:A接收到B的FIN包后,向B发送ACK包,表示“收到FIN包,准备关闭连接”,然后等待所有数据包的传输完成后,断开连接。 如果在A方发送第一个FIN包时B方数据已经全发完了,那可不可以只要两次挥手 不可以。因为TCP协议是全双工的,数据在两个方向上独立地进行传输。因此,每个方向都需要单独关闭。 题设的条件下,即使B方的数据传输已经完成,但是A方并不知道这一点。因此,B方需要发送FIN包来示意A方已经完成数据传输。并且,A方需要发送ACK包来确认收到FIN包。这样两个方向都进行了两次挥手,总共四次,来确保连接可以安全地关闭。