摘自:http://www.cnblogs.com/artech/p/restful-web-api-01.html
一、TCP/IP与HTTP
TCP/IP是以IP和TCP协议为核心的一整套网络协议的总称,所以有时候我们也称其为TCP/IP协议簇。毫不夸张地说,TCP/IP支撑着整个互联网,因为它就是互联网采用的网络协议。TCP/IP协议簇划分为如右图所示的4个层次[2](应用层、传输层、网络层和链路层),构成整个协议簇的各个子协议处于相应层次中。
既然将整个协议簇命名为TCP/IP,那么IP和TCP自然就是其中最为核心的两个协议了。处于网络层的IP协议提供的IP数据报传输是不可靠的,因为它只承诺尽可能地将数据报发送出去,但不能保证发送的数据报能够成功地抵达目的地。IP协议的不可靠性还体现在它不能检测数据在传输过程中是否发生了改变,也就是说数据的完整性得不到保证。IP协议是一个无连接(Connectionless)的网络协议,每次数据报的处理对它来说均是独立的,因此IP协议也不能提供针对有序传输(数据接收的顺序与发送的顺序一致)的保证。
虽然IP协议只能提供不可靠的数据传输,同时有序传输也得不到保证,但是建立在它之上的传输层协议TCP有效地解决了这两个问题。TCP是一个基于连接的协议,数据交换双方在进行报文传输之前需要建立连接,报文传输结束之后需要关闭连接。这是一个双工(Duplex)连接,数据交换的双工均可以利用它向对方发送数据。
TCP利用“接收确认”和“超时重传”机制确保了数据能够成功抵达目的地。具体来说,接收方在成功接收到数据之后会回复一个确认消息。发送方在本地具有一个存放尚未得到确认的已发消息的缓冲区,如果发送方在一个设定的时限内没有接收到针对某个已发报文的确认消息,它会从该缓存区中选择对应的报文进行重新发送。在接收到确认之后,相应的报文会从缓存区中移除。
为了解决有序传输的问题,发送方会为每个报文进行编号,报文的序号体现了它们被发送的顺序。接收端在接收到某个报文之后,它会利用此序号判断是否具有尚未成功接收的已发报文,如果有的话,该报文会被存放到本地的缓冲区中。等到之前发送的报文全部被接收之后,接收方按照序号对接收的报文依次向上(应用层)递交,成功递交的报文会被从缓存区中移除。除了接收到“失序”的报文之外,接收方还有可能接收到重复的报文,因为没有报文均具有一个唯一的序号,如果该序号小于已经成功递交或者添加到缓存区中的报文序号,它会被认为是重复接收的报文而被丢弃。
由于每个TCP报文段都具有一个16位的检验和(Checksum),所以接收方可以根据它确认数据在传输过程中是否被篡改。除此之外,TCP还提供了“流量控制”功能避免了双方因缓存区大小不一致而导致报文丢失。具体来说,如果发送方的缓冲区大于接收方的缓存区,会导致接收方在缓冲区已满的情况下无法处理后续接收的报文,所以接收方会将自己缓存区剩余的大小及时通知给发送端,后者据此控制报文发送“流量”。
HTTP(Hypertext Transfer Protocol),全称为“超文本传输协议”,是TCP/IP协议簇的一部分。从图1-1可以看出,这是一个位于应用层的网络协议,在它之下的就是TCP协议。由于TCP协议是一个“可靠”的协议,HTTP自然也能提供可靠数据传输功能。
IP协议利用IP地址来定位数据报发送的目的地,而利用域名系统(DNS)可以实现域名与IP地址之间的转换。TCP协议利用端口号标识应用程序,所以某个应用程序在使用TCP协议进行通信的时候必须指定目标应用的IP地址(或者域名)和端口号。HTTP默认采用的端口号为80,而HTTPS(利用TLS/SSL为HTTP提供传输安全保障)的默认端口号则为443,当然在网络可达的前提下,我们可以指定任意的端口。
响应状态码
针对客户端向Web服务器发送的任意一个HTTP请求,不论在何种情况下得到一个响应,每个响应均具有一个由3位数字表示的状态码和相应的描述文字。不同数值的状态码体现了不同类型的响应状态,W3C对响应状态码的范围作了如下的规范。
- 100~199:信息状态码,代表请求已被接受,需要继续处理。
- 200~299:成功状态码,代表请求已成功被服务器接收、理解、并接受。
- 300~399:重定向状态码,代表需要客户端采取进一步的操作才能完成请求。
- 400~499:客户端错误状态码,代表了客户端看起来可能发生了错误,妨碍了服务器的处理。
- 500~599:服务器错误状态码,代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。
四、HTTP报文
客户端和Web服务器在一次HTTP事务中交换的消息被称为HTTP报头,客户端发送给服务器的请求消息被称为请求报文,服务器返回给客户端的响应消息被称为响应报头。请求报文和响应报头采用纯文本编码,由一行行简单的字符串组成。一个完整的HTTP报文由如下三个部分构成。
- 起始行:代表HTTP报文的第一行文字,请求报文利用起始行表示采用的HTTP方法、请求URI和采用的HTTP版本,而响应报文的起始行在承载着HTTP版本和响应状态码等信息。
- 报头集合:HTTP报文的起始行后面可以包含零个或者多个报头字段。每个报头表现为一个键/值对,键和值分别表示报头名称和报头的值,两者通过冒号(“:”)进行分割。HTTP报文采用一个空行作为报头集合结束的标志。
- 主体内容:代表报头集合结束标志的空行之后就是HTTP报文的主体部分了。客户端提交给服务器的数据一般置于请求报头的主体,而响应报头的主体也承载着服务器返回给客户端的数据。不论是请求报文还是响应报文,其主体部分均是可以缺省的。
接下来我们看看一个具体HTTP报文具有怎样的结构。下面这个文本片段反映的是我们通过Chrome浏览器访问微软的官网(www.microsoft. com)对应的HTTP请求,起始行体现了HTTP请求的三个基本属性,即HTTP方法(GET)、目标资源(http://www.microsoft.com/en-us/default.aspx)和协议版本(HTTP/1.1)。
1: GET http://www.microsoft.com/en-us/default.aspx HTTP/1.1
2: Host: www.microsoft.com
3: Connection: keep-alive
4: Cache-Control: max-age=0
5: User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.75 Safari/535.7
6: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
7: Accept-Encoding: gzip,deflate,sdch
8: Accept-Language: en-US,en;q=0.8
9: Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
10: Cookie: ...
上述这个请求报文不具有主体,所以起始行之外的所有内容均为报头集合,我们们可以根据这些报头获得主机名称、采用的缓存策略、浏览器相关信息、以及客户端支持的媒体类型(Media Type)、编码方式、语言和字符集等。
前面的HTTP请求通过浏览器发送给服务端之后会接收到具有如下结构的响应报文,我们可以此从它的起始行得到采用的HTTP版本(HTTP/1.1)和响应状态码(“200 OK”,表示请求被正常接收处理)。响应的内容被封装到响应报文的主体部分,其媒体类型的通过报头“Content-Type”表示。由于该响应报文的主体内容是一个HTML文档,所以“Content-Type”报头表示的媒体类型为“text/html”。
1: HTTP/1.1 200 OK
2: Cache-Control: no-cache
3: Pragma: no-cache
4: Content-Type: text/html; charset=utf-8
5: Content-Encoding: gzip
6: Expires: -1
7: Vary: Accept-Encoding
8: Server: Microsoft-IIS/7.5
9: X-AspNet-Version: 2.0.50727
10: VTag: 791897542300000000
11: P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
12: X-Powered-By: ASP.NET
13: Date: Wed, 18 Jan 2012 07:06:25 GMT
14: Content-Length: 34237
15:
16:
17: …
[1]超文本/超媒体(HyperText/HyperMedia):超文本是一份呈现文本内容的电子文档,其核心在于可以利用内嵌的“超链接(Hyperlink)”直接访问引用的另一份文档。超媒体对超文本作了简单的扩展以呈现多媒体内容(比如图片、音频和视频等)。HTML文档是我们常见的最为典型的超文本/超媒体文件。
[2] 除了采用这种4个层次的划分方法之外,还具有另外两种典型的划分方式。其中一种在链路层下面添加一个基于物理网络硬件的物理层,这种划分方法与此没有本质的区别。另外一种则是将TCP/IP协议簇划分为包括应用层、表示层、会话层、传输层、网络层、链路层和物理层在内的7个层次