在讲HTTP、TCP、UDP之前先来看下TCP/IP五层网络架构
TCP/IP通信数据流:
TCP/IP
协议族中有一个重要的概念是分层,TCP/IP协议
按照层次分为以下四层。应用层、传输层、网络层、数据链路层、物理层
。其中TCP、UDP
属于传输层协议,而HTTP
是基于 TCP/IP
协议的应用层协议,它不涉及数据包传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口。
物理层:
规定通信设备的机械的、电气的、功能的和过程的特性,用以建立、维护和拆除物理链路连接;在这一层,数据的单位称为比特(bit)。属于物理层定义的典型规范代表包括:EIA/TIA RS-232、EIA/TIA RS-449、V.35、RJ-45等。
数据链路层:
在物理层提供比特流服务的基础上,建立相邻结点之间的数据链路,通过差错控制提供数据帧(Frame)在信道上无差错的传输,并进行各电路上的动作系列。数据链路层在不可靠的物理介质上提供可靠的传输。该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。在这一层,数据的单位称为帧(frame)。数据链路层协议的代表包括:SDLC、HDLC、PPP、STP、帧中继等。
网络层
:
在 计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。网络层将数据链路层提供的帧组成数据包,包中封装有网络层包头,其中含有逻辑地址信息- -源站点和目的站点地址的网络地址
传输层:
网络层负责点到点的传输(这里的"点"指主机或路由器),而传输层负责端到端的传输(这里的"端"指源主机和目的主机),提供应用程序间的通信。其功能包括:格式化信息流、提供可靠传输。为实现后者,传输层协议规定接收端必须发回确认,并且假如分组丢失,必须重新发送。传输层协议主要是:传输控制协议TCP
和用户数据报协议UDP
。在这一层,数据的单位称为 段
应用层:
应用层为操作系统或网络应用程序提供访问网络服务的接口,向用户提供一组常用的应用程序,比如电子邮件、文件传输访问、远程登录等应用层,协议的代表包括:Telnet、FTP、HTTP、SNMP等。
TCP/UDP
TCP
和UDP
协议属于传输层协议。其中TCP
提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。通俗说,它是事先为所发送的数据开辟出连接好的通道,然后再进行数据发送;而UDP
则不为IP提供可靠性、流控或差错恢复功能。一般来说,TCP
对应的是可靠性要求高的应用,而UDP
对应的则是可靠性要求低、传输经济的应用。
1、面向连接的 TCP:
“面向连接”就是在正式通信前必须要与对方建立起连接。比如你给别人打电话,必须等线路接通了、对方拿起话筒才能相互通话。
TCP
是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP
连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,我们这里只做简单、形象的介绍如下图:
TCP
使用窗口机制进行流量控制:连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端,接收方发送的确认信息中包含了自己剩余的缓冲区尺寸,剩余缓冲区空间的数量叫做窗口。TCP
的流控过程(滑动窗口):2、面向非连接的 UDP
“面向非连接”就是在正式通信前不必与对方先建立连接,不管对方状态就直接发送。与手机短信非常相似:你在发短信的时候,只需要输入对方手机号就OK了。
UDP
适用于一次只传送少量数据、对可靠性要求不高的应用环境。比如,我们经常使用“ping”命令来测试两台主机之间TCP/IP
通信是否正常,其实“ping”命令的原理就是向对方主机发送ICMP数据包
,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。例如,在默认状态下,一次“ping”操作发送4个数据包(如图所示)。大家可以看到,发送的数据包数量是4包,收到的也是4包(因为对方主机收到后会发回一个确认收到的数据包)。这充分说明了UDP协议
是面向非连接的协议,没有建立连接的过程。正因为UDP协议
没有连接的过程,所以它的通信效率高;但也正因为如此,它的可靠性不如TCP协议
高。QQ就使用UDP
发消息,因此有时会出现收不到消息的情况。
TCP协议
和UDP协议
各有所长、各有所短,适用于不同要求的通信环境。TCP协议
和UDP协议
之间的差别如附表所示:
TCP使用场景:
对数据传输可靠性要求非常高,例如大家浏览网页,通过网页注册帐号、转帐等服务,这是不容许出错的,使用TCP协议
能把出错的可能性降到最低(当然,网络自身很糟糕,TCP协议
也没办法)。但是,提供这种可靠服务,会加大网络带宽的开销,因为“虚拟信道”是持续存在的,同时网络中还会出现大量的ACK
和FIN
包!
UDP使用场景:
TCP协议
提供了可靠的数据传输,但是其拥塞控制、数据校验、重传机制的网络开销很大,不适合实时通信,所以选择开销很小的UDP协议
来传输数据。 UDP 协议
是无连接的数据传输协议并且无重传机制,会发生丢包、收到重复包、乱序等情况。而对于数据精确性要求不高的状态数据以及视频数据,丢包的影响不大。因为会不断收到新的包,丢失的个别包会有新的包来覆盖,所以只需在远程控制系统的通信部分自行处理乱序及重复包的问题,而对于丢包的问题一般不作处理。 但对于命令包这种需要精确收发的数据, 可在程序的开发中加入丢包重发和超时丢弃的处理。 当然,如果开发的是对于实时性要求不高的事件型控制命令的传输,不希望发生指令的丢失也可以直接采用TCP协议
。TCP
的重传机制正好适合这种情况
HTTP
超文本传输协议
(HTTP
)是互联网上应用最为广泛的一种网络协议。所有的WWW文件
都必须遵守这个标准。
通常,由HTTP
客户端发起一个请求,建立一个到服务器指定端口(默认是80端口)的TCP
连接。HTTP
服务器则在那个端口监听客户端发送过来的请求。一旦收到请求,服务器(向客户端)发回一个状态行,比如"HTTP/1.1 200 OK"
,和(响应的)消息,消息的消息体可能是请求的文件、错误消息、或者其它一些信息。HTTP
使用TCP
而不是UDP
的原因在于(打开)一个网页必须传送很多数据,而TCP
协议提供传输控制,按顺序组织数据,和错误纠正。
工作流程:
一次
HTTP
操作称为一个事务,其工作过程可分为四步:1)首先客户机与服务器需要建立连接。只要单击某个超级链接,
HTTP
的工作开始。2)建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是
MIME
信息包括请求修饰符、客户机信息和可能的内容。3)服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是
MIME
信息包括服务器信息、实体信息和可能的内容。4)客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接。
如果在以上过程中的某一步出现错误,那么产生错误的信息将返回到客户端,有显示屏输出。对于用户来说,这些过程是由
HTTP
自己完成的,用户只要用鼠标点击,等待信息显示就可以了。HTTP协议
永远都是客户端发起请求,服务器回送响应,这样就限制了使用HTTP协议
,无法实现在客户端没有发起请求的时候,服务器将消息推送给客户端。HTTP协议
是一个无状态的协议,同一个客户端的这次请求和上次请求是没有对应关系。HTTP请求和回应
除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。其他的功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等
使用Wireshark抓TCP、http包:
在上图中,可清晰的看到客户端浏览器(ip为192.168.2.33)与服务器的交互过程:
1)No1:浏览器(192.168.2.33)向服务器(220.181.50.118)发出连接请求。此为TCP三次握手第一步,此时从图中可以看出,为SYN,seq:X (x=0) 2)No2:服务器(220.181.50.118)回应了浏览器(192.168.2.33)的请求,并要求确认,此时为:SYN,ACK,此时seq:y(y为0),ACK:x+1(为1),此为三次握手的第二步; 3)No3:浏览器(192.168.2.33)回应了服务器(220.181.50.118)的确认,连接成功。为:ACK,此时seq:x+1(为1),ACK:y+1(为1)。此为三次握手的第三步; 4)No4:浏览器(192.168.2.33)发出一个页面HTTP请求; 5)No5:服务器(220.181.50.118)确认; 6)No6:服务器(220.181.50.118)发送数据; 7)No7:客户端浏览器(192.168.2.33)确认; 8)No14:客户端(192.168.2.33)发出一个图片HTTP请求; 9)No15:服务器(220.181.50.118)发送状态响应码200 OK ……
请求格式(Charles抓包工具):
以请求网址http://image.baidu.com/为例
请求:
响应:
第一行是请求命令,必须在尾部添加协议版本
HTTP/1.1
。后面就是多行头信息,描述客户端的情况。
回应格式
服务器的回应如下:
回应的格式是头信息 + 一个空行(\r\n) + 数据
。其中,第一行是协议版本 + 状态码(status code) + 状态描述
。
host头域:
Host头域
指定请求资源的Intenet主机和端口号,必须表示请求url的原始服务器或网关的位置。HTTP/1.1
请求必须包含主机头域,否则系统会以400
状态码返回。
图中host那行为:
Host image.baidu.com
Referer头域
Referer头域允许客户端指定请求uri的源资源地址,这可以允许服务器生成回退链表,可用来登陆、优化cache等。他也允许废除的或错误的连接由于维护的目的被追踪。如果请求的uri没有自己的uri地址,Referer不能被发送。如果指定的是部分uri地址,则此地址应该是一个相对地址。
在图中,Referer行的内容为:
Referer http://image.baidu.com
User-Agent头域
User-Agent
头域的内容包含发出请求的用户信息。
在图中,User-Agent行的内容为:
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14
Cache-Control头域
Cache-Control
指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control
并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached
,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age
。
Date头域
Date头域
表示消息发送的时间,时间的描述格式由rfc822
定义。例如,Date:Mon,31Dec200104:25:57GMT
。Date
描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。
图中,该头域如下图所示:
Date Thu, 01 Dec 2016 08:07:52 GMT
Content-Type字段:
关于字符的编码,1.0版规定,头信息必须是 ASCII 码,后面的数据可以是任何格式。因此,服务器回应的时候,必须告诉客户端,数据是什么格式,这就是Content-Type
字段的作用。
下面是一些常见的Content-Type
字段的值:
text/plain
text/html
text/css
image/jpeg
image/png
image/svg+xml
audio/mp4
video/mp4
application/javascript
application/pdf
application/zip
application/atom+xml
这些数据类型总称为MIME type
,每个值包括一级类型和二级类型,之间用/
分隔。除了预定义的类型,厂商也可以自定义类型。
application/vnd.debian.binary-package
上面的类型表明,发送的是Debian系统的二进制数据包。
MIME type
还可以在尾部使用分号,添加参数:
Content-Type: text/html; charset=utf-8
上面的类型表明,发送的是网页,而且编码是UTF-8
。
客户端请求的时候,可以使用Accept
字段声明自己可以接受哪些数据格式。
Accept: */*
上面代码中,客户端声明自己可以接受任何格式的数据。
MIME type
不仅用在HTTP协议
,还可以用在其他地方,比如HTML
网页。
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- 等同于 -->
<meta charset="utf-8" />
Content-Encodeing字段
由于发送的数据可以是任何格式,因此可以把数据压缩后再发送。Content-Encoding
字段说明数据的压缩方法:
Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate```
客户端在请求时,用`Accept-Encoding`字段说明自己可以接受哪些压缩方法:
`Accept-Encoding: gzip, deflate`
#### http 1.1中新的功能:
#####持久连接:
1.1 版的最大变化,就是引入了持久连接,即`TCP`连接默认不关闭,可以被多个请求复用,不用声明`Connection: keep-alive`。
`HTTP/1.0` 每次请求都需要建立新的`TCP`连接,连接不能复用。`HTTP/1.1 `新的请求可以在上次请求建立的`TCP`连接之上发送,连接可以复用。优点是减少重复进行`TCP`三次握手的开销,提高效率。
客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送`Connection: close`,明确要求服务器`关闭TCP连接`。
在`http1.1`,`request`和`reponse`头中都有可能出现一个`connection`的头,此`header`的含义是当`client`和`server`通信时对于长链接如何进行处理。
`clien`t和`server`都是默认对方支持长链接的, 如果`client`使用`http1.1协议`,但又不希望使用长链接,则需要在`header`中指明`connection`的值为`close`;如果`server`方也不想支持长链接,则在`response`中也需要明确说明`connection`的值为`close`。不论`request`还是`response`的`header`中包含了值为`close`的`connection`,都表明当前正在使用的`TCP`链接在当天请求处理完毕后会被断掉。以后`client`再进行新的请求时就必须创建新的`TCP`链接了。
注意:在同一个`TCP`连接中,新的请求需要等上次请求收到响应后,才能发送。
测试如下
终端输入:
telnet www.baidu.com 80```
结果如下:
Trying 115.239.210.27...
Connected to www.a.shifen.com.
Escape character is '^]'.```
接着开始发请求消息,例如发送如下请求消息请求baidu的首页消息,使用的`HTTP`协议为`HTTP/1.1`:
GET /index.html HTTP/1.1```
注意:copy如上的消息到终端后需要按两个回车换行才能得到响应的消息,第一个回车换行是在命令后键入回车换行,是HTTP
协议要求的。第二个是确认输入,发送请求。
最终结果:
![](http://upload-images.jianshu.io/upload_images/1964261-47760b45fe9b7bd6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 可看到,当采用
HTTP/1.1`时,连接不是在请求结束后就断开的。等待几秒钟之后断开,输出:
Connection closed by foreign host.
若采用HTTP1.0
,在命令窗口键入:
GET /index.html HTTP/1.0```
此时可以看到请求结束之后马上断开
读者还可以尝试在使用`GET`或`POST`等时,带上头域信息,例如键入如下信息:
GET /index.html HTTP/1.1
connection: close
Host: www.baidu.com```
http的状态响应码
http的状态响应码
请求收到,继续处理:
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
操作成功收到,分析、接受:
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
完成此请求必须进一步处理:
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
请求包含一个错误语法或不能完成:
400-错误请求,如语法错误
401——未授权
HTTP 401.1 - 未授权:登录失败
HTTP 401.2 - 未授权:服务器配置问题导致登录失败
HTTP 401.3 - ACL 禁止访问资源
HTTP 401.4 - 未授权:授权被筛选器拒绝
HTTP 401.5 - 未授权:ISAPI 或 CGI 授权失败
402——保留有效ChargeTo头响应
403——禁止访问
HTTP 403.1 禁止访问:禁止可执行访问
HTTP 403.2 - 禁止访问:禁止读访问
HTTP 403.3 - 禁止访问:禁止写访问
HTTP 403.4 - 禁止访问:要求 SSL
HTTP 403.5 - 禁止访问:要求 SSL 128
HTTP 403.6 - 禁止访问:IP 地址被拒绝
HTTP 403.7 - 禁止访问:要求客户证书
HTTP 403.8 - 禁止访问:禁止站点访问
HTTP 403.9 - 禁止访问:连接的用户过多
HTTP 403.10 - 禁止访问:配置无效
HTTP 403.11 - 禁止访问:密码更改
HTTP 403.12 - 禁止访问:映射器拒绝访问
HTTP 403.13 - 禁止访问:客户证书已被吊销
HTTP 403.15 - 禁止访问:客户访问许可过多
HTTP 403.16 - 禁止访问:客户证书不可信或者无效
HTTP 403.17 - 禁止访问:客户证书已经到期或者尚未生效
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求长。
服务器执行一个完全有效请求失败:
HTTP 500 - 内部服务器错误
HTTP 500.100 - 内部服务器错误 - ASP 错误
HTTP 500-11 服务器关闭
HTTP 500-12 应用程序重新启动
HTTP 500-13 - 服务器太忙
HTTP 500-14 - 应用程序无效
HTTP 500-15 - 不允许请求 global.asa
Error 501 - 未实现
HTTP 502 - 网关错误