今天周末时间,有空给大家讲解一个小知识点,即HTTP的keep-alive头部。我使用wireshark来抓取网络包来在实战中讲解。希望能让大家更容易、更直观的理解!
HTTP中keep-alive头部的作用是为保持TCP连接,这样可以复用TCP连接不需要为每个HTTP请求都建立一个单独的TCP连接。这样既可以节省操作系统资源,也能够保持HTTP请求的高效性。
我们通过wireshark抓的包来分析一下:
下面的例子中128.14.154.105是HTTP服务器,192.168.1.6是客户端。
当服务器处理完一个HTTP请求时,会主动发起断开连接,如下图所示(四次挥手):
当服务器最后发送一个ACK包后进入TIME_WAIT状态,此状态将会持续2MSL(Maximum Segment Lifetime),一个MSL一般为2分钟,所以TIME_WAIT一般持续4分钟。在此期间还是可以接受客户端的数据的。
此时客户端为了复用TCP连接,将会发送一个心跳包(keep-alive)来保持连接。
上面的例子中,共发送了2次心跳包。如果在此期间还没有新的HTTP请求那么服务器会再次主动断开。
此后,客户端不会再发送心跳包了。
在最后给大家说下,为什么主动发起断开连接的一方在发送最后一个ACK包后需要进入TIME_WAIT状态2MSL。
1)我们先假设发送完最后一个ACK包后直接断开的话,如果由于某种原因对端没有收到的话,对端会再次发送一个FIN包(TCP的重传机制),由于此时另一端已经关闭了对应的socket,所以TCP协议栈会
发送一个RST包。这个包表示的是一种错误。(比如,请求的TCP连接的端口没有在监听状态下),那么TCP连接就是因错误而被迫断开,所以TCP中工作没有正常完成。
2)第二个原因是让老的重复包在网络中消失,解释一下这句话的意思:如果我们的TCP断开之后,立马有一个新的TCP连接和之前的连接的IP和端口都一样的话,那么残留在网络中的包到达后会被误解为是新的
连接中的包。这样就会出现问题。如果我们使用了TIME_WAIT,在这个状态下是不允许建立新的IP和端口都一样的TCP连接的,而且它会维持2MSL时间, 这足够让网络中的旧包消失掉。
最后欢迎大家评论指正!^_^