《HTTP: The Definitive Guide》读书笔记

将之前在skydriver的读书笔记挪出来,在skydriver里实在是不方便阅读,虽然很炫。

Htpp请求综述: 

HTTP http分为request response两种请求。  

请求分为请求头和请求体,请求体可能为空。请求头包括method,URL,version,status code,reason-phrase,headers参数。 

  • Method  

其中,request 的method有get(拿资源),post(传表单),trace(从客户端到服务器之间可能经过网关、代理、防火墙等等。它们都可能改请求,使用trace可以从response返回一路经过的设备和简洁明信息供判断)put(写资源、存储)head(请求一个资源只返回请求头,用于判断文件是否存在、权限等),但不是所有的方法都支持,HTTP1•1只要求支持get)故可以用option(返回服务器支持的所有方法类型)另还有delete等等,和其它拓展方法。  

  • Version  

  • Status code  

  • Reason-phrase  

  • Headers 

 

Http请求的步骤: 

  1. 浏览器的地址栏获取主机名 

  2. 通过Domain Name System通过主机名解析目标主机IP。 

  3. 从浏览器的地址栏获取端口号。 

  4. 经历三次握手,建立到目标主机某一端口的TCP管道 

  5. 发送Http请求 

  6. 接受响应 

  7. 关闭TCP连接 

 

图像

 

 

TCP/IP协议参考模型和OSI参考模型 

 

图像

 

 

 

Http和TCP/IP协议参考模型的关系 

图像

 

底层Socket实现步骤 

图像

 

建立TCP协议的三次握手(Handshake) 

HTTP底层基于TCP协议,地址栏输入URL后,浏览器请求DNS解析出主机IP和端口号,试图向Server建立TCP连接来发送请求。建立TCP连接的详细过程是: 

  1. 请求一个TCP连接时,Client会先发送一个很小的、带有“SYN=j”标识的TCP数据包,并进入SYN_SEND状态,等待服务器确认 

  2. Server接收到一个数据包,发现有“SYN”标识,则意味着某个Client在向其请求连接,Server计算一些参数放到将要发回Client的报文中,即此报文含有“SYN=k”和“ACK=j+1”标识,意味着Server已经同意建立连接,此时服务器进入SYN_RECV状态。 

  3. 最后,客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。完成三次握手,客户端与服务器开始传送数据。 

对于B/S架构的软件来说,浏览器就是Client,HTTP协议在第三次握手时(图中的c步骤)已经开始将HttpRequest的信息放到报文中。 

图像

 

影响Http效率的【TCP协议】原因 

  • The TCP Connection Setup Handshake:TCP的三次握手创建链接时耗费了大部分时间。 

  • Delay Acknowledgement:网络传输不保证数据包的完整性,如路由器过载时会毁坏报文,TCP协议为保证数据完备性实现了Delay Acknowledgement算法:在server发送的报文中(TCP segment)含有一个序列号,当client接受到报文,会发送一个很小的“acknowledgement”报文。用于向server确认已经收到。由于client要发的acknowledgement报文比较小,TCP的Client通常把它放到要发回给Server的报文中一起发,以最小限度减少网络传输,如果等一会儿(通常100-200毫秒)Client还没有要返回给Server的报文,Client就单独将acknowledgement发送给Server。在此之前Server也一直等着,一定的时间没有收到Client过来的报文,Server认为之前发给Client的报文已经损坏,将会重发。 

    以上算法本来在TCP中是为了减少报文的数量,但HTTP得双峰型结构,使得发回Server的报文太少,Client收到报文后不能及时将acknowledgement发回去,而需要等一段时间,因而耽误了传输。 

  • TCP Slow Start:TCP的慢启动,连接建立起来之后,为了保证不过载。Server不是马上就大量传输数据,而是"TCP connection 'tuen' themselves overtime",当连接初始化时,TCP会限制最大传输速度,当传输正常之后(有acknowledgement包回来),速度逐渐倍增(X2)直到最大。这个过程叫做"opening congestion window"。这个特性叫做TCP Slow Start 

  • TCP Nagle Algorithm:TCP的报文可以在TCP栈中以任意大小传输,甚至一个segment1字节也可以,但是一个segment最少要携带40byte的信息,所以当大量发送小数据量的segment时,TCP的效率就被浪费。TCP的Nagle算法通常是用于解决当segment太小时,将报文信息缓存起来,足够大或者收到Client的acknowledgement报文之后才会发送,这样将减少小包频繁发送。(在IETF RFC 896有描述) 

    但是在HTTP中,这个算法引来了严重的效率问题,因为"Nagle Algorithm let's you send a non-full-packet only if all other packet are acknowleged."也就是说,Nagle算法会把我们的报文一直攒到最大(LAN下是1500byte,internet是几百byte)或者其他所有的包都返回acknowledgement确认之后才会发送。由于HTTP的报文经常很小,不容易达到maxnum-size paket,所有常常被这个算法缓存起来不发送。之前提到过,我们的acknowledgement又有延迟的情况,所有这两者在一起会产生更恶劣的互相影响。 

    当然,Nagle Algorithm可以在应用中用TCP_NODELAY来禁止。但是注意会有小包频发的问题。 

  • TIME_WAIT Accumulatin and Port Exhaustion:当TCP连接关闭时,主动关闭的一方(HTTP中是Server主动关闭)要发送一个最终的ACK segment,同时其进入TIME_WAIT而不是CLOSED状态。该状态会记录刚关闭这个链接的IP和端口。这个最后的ACK数据段可能丢失,这时候另一方会重发FIN。如果FIN再次到达,而主动关闭的这一方是CLOSED状态,就会响应RST分节,在被动端将解析错误,Java中会抛出connection reset的SocketException. 

因而主动关闭端维持2MSL(twice maximum segment lifetime最大分节生命期)的TIME_WAIT,以便当最后一个ACK丢失之后,接到另一端的FIN还能重发ACK。同时在此时防止segment去请求记录的同一个IP和端口的连接。(因为路由故障或其他原因,会有一些迷途segment过一段时间才会到达。由于已经重发,所以这些迟到的重复的stray dumplicate pakets会请求关闭的连接,由于是TIME_WITE状态,不允许这些包请求同一IP、端口的连接。) 

【TCP的关闭过程和TIME_WAIT 

 

 

 

HTTP的优化策略 

  • parallel connections:同时使用多个连接如请求页面的元素,而不是用一个连接去逐一加载。但浏览器也不会无限制地创建连接去请求server,这样server会过载,一般如四个连接,同时去请求四个元素。 

  • persistent connections: 

 

MIT的算法书 introduction to algorithms 

 

图像

 

posted @ 2013-01-07 16:08  大树的博客  Views(290)  Comments(0Edit  收藏  举报