一、网络模型
网络模型一般是指OSI七层参考模型和TCP/IP四层参考模型。这两个模型在网络中应用最为广泛。
提问:各层的网络协议有哪些?(以下只是部分)
- 应用层:HTTP、SMTP、SSH
- 传输层:TCP、UDP
- 网络层:IP、路由表
- 网络接口层:以太网
二、TCP/IP协议数据流
三、TCP连接
1、TCP连接的特点:
- 面向连接的、可靠的传输协议。
- TCP连接不是物理连接(不是电线的两端连接),只有建立TCP连接之后,客户端和服务端才可以开辟资源,比如建立Socket连接。
- 用户进程与服务器进程完成一次通信都需要完成三个阶段:建立连接、传输数据、断开连接。
- TCP建立连接需要三次握手,断开连接需要四次挥手。
2、TCP连接过程
(本文暂时跳过了序列号seq和确认号ack的讲解,只讲以下3个标志位)
(1)标志位
- SYN(Synchronize):发起建立连接的标志。
- ACK(Acknowledge):确认/应答的标志。
- FIN(Finally):发起断开连接的标志。
(2)TCP连接的两端
- 客户端:主动打开/关闭连接的一方。
- 服务端:被动打开/关闭连接的一方。
(3)三次握手过程:
- 第一次握手:客户端首先发送一个带有SYN的报文给服务端,表示请求建立连接,并进入SYN-SENT(同步已发送)状态,等待服务端确认。
- 第二次握手:服务端发送一个带有SYN+ACK的报文给客户端,表示收到并确认客户端发送的连接请求报文,同时服务端也请求和客户端建立连接,此时服务端进入SYN-RCVD(同步收到)状态。
- 第三次握手:客户端会再一次发送一个带有ACK的报文给服务端,表示客户端也确认收到服务端的应答和连接请求报文。当服务端收到报文后,客户端和服务端进入ESTAB-LISHED(已建立连接)状态,至此完成三次握手,双方正式建立了连接通信,可以进行数据传输。
提问:为什么TCP建立连接是三次握手而不能是两次握手?
通信是双向的,目的是为了双方彼此建立可靠的连接。如果仅仅是两次握手,仅客户端能够确认服务端的应答,而服务端无法确认客户端是否收到服务端的连接请求,所以客户端仍需再一次发送ACK报文给服务端表示应答,服务端收到后双方才算正式建立连接通信。
(4)四次挥手过程:
- 第一次挥手:客户端首先发送一个带有FIN的报文给服务端,表示请求断开连接,即客户端已经没有数据要发送了,此时客户端进入FIN-WAIT-1(终止等待1)状态。
- 第二次挥手:服务端发送一个带有ACK的报文给客户端,表示确认收到客户端的断开连接请求报文,此时服务端进入CLOSE-WAIT(关闭等待)状态。客户端收到服务端的应答后,客户端就进入FIN-WAIT-2(终止等待2)状态。这个时候如果服务端继续发送数据,客户端依然要接受。
- 第三次挥手:服务端在最后的数据发送完毕后,会再次发送一个带有FIN+ACK的报文给客户端,表示服务端此时同意断开连接,并向客户端请求断开连接,此时服务端进入LAST-ACK(最后确认)状态。
- 第四次挥手:客户端再次收到服务端的应答和断开连接请求报文后,会再一次发送一个带有ACK的报文给服务端,表示客户端也确认收到服务端的断开连接请求,此时客户端就进入了TIME-WAIT(时间等待)状态,当服务端收到客户端的应答报文后,就立刻进入CLOSED(关闭连接)状态,而客户端必须经过2MSL(最长报文段寿命)的时间、并且这个期间没有再次收到FIN报文,才进入CLOSED状态。可以看到,服务端结束TCP连接的时间要比客户端早一些。
提问:为什么TCP断开连接需要四次挥手?
因为TCP连接建立的是可靠的连接。当服务端收到FIN报文后,很可能不会立即关闭Socket,因为此时服务端的数据传输可能还没发送完毕,所以此时只能先回一个ACK报文,告诉客户端:“你发的FIN报文我收到了,只有等我所有数据都发送完毕,我才能发送FIN报文给你”。因此不能在第二次挥手的时候就一起发送ACK+FIN报文,故需要四次挥手。
提问:为什么客户端TIME_WAIT状态需要等待2MSL(最大报文段生存时间)才能进入CLOSE状态?
假设网络是不可靠的,有可能客户端最后发送的ACK报文丢失,此时服务端没有收到客户端的应答,会不断发送FIN报文给客户端,所以TIME-WAIT状态就是客户端用来重发可能丢失的ACK报文,它必须确认服务端收到了ACK报文。客户端会设置一个计时器,等待2MSL的时间,如果在该时间内再次收到FIN报文,客户端会重发ACK数据并再次等待2MSL,直到这2MSL时间内都没收到服务端的FIN报文,客户端才推断ACK报文被服务端成功接收,此时才结束客户端的TCP连接。
(所谓的2MSL是指两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最长时间)
补充:知乎上有个形象的示例,再次说明TCP连接为什么是三次握手,而不是两次或四次?