TCPIP协议详解
第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
补充:这里有个状态TIME_WAIT要注意一下。首先,TIME_WAIT是主动提出关闭的一方,再发出确认报文后进入的状态,通常持续2MSL时长。(对于MSL,其指的是报文段的最大生存时间)
TIME_WAIT有什么作用呢?被动关闭的一方因为网络延迟等原因没收到最后的确认报文,所以再次发送FIN报文。TIME_WAIT状态的主动关闭方收到这些报文后,会把这些尾巴问题处理掉,不至于对新连接及其他服务产生影响。
TCP TIME_WAIT状态解析及问题解决
以下为本人通俗化的理解
三次握手
- 客户端:我能和你连接么?!(客户端请求与服务器进行连接,发出请求包)
- 服务器收到请求后:可以啊!但你确定要和我连接么?(服务器同意连接后一并发送确认包和之前的请求包)
- 客户端:我确定!!(客户端把请求包再重新发送给服务器以表决心)
四次挥手(因为是连接是全双工的,所以可以同一时间相互发数据)
- 客户端:我已经没有东西要发给你了!(客户端发送完毕,向服务器表示不再发送数据)
- 服务器:嗯的,好的(服务器先回应客户端,表示知道他不会再发数据了,但是服务器自己可能数据还没传递完,所以暂时先不告诉客户端断开连接)
- 服务器:我这里也没有东西要发给你了,我们断开连接吧!(服务器确认好自己没有要发的数据了,告诉客户端可以断开连接)
- 客户端:那我们就断开吧(客户端回应服务器)
为什么要三次握手,而不是两次
- 可能会因为网络延迟,第一次的请求在第二次的请求的连接都结束后才送到,如果服务器不再三确认直接建立连接,会浪费大量资源(也就是服务器和客户端建立连接后什么事情都没做,光耗着)