Web浏览器、服务器和相关的Web应用程序都是通过HTTP相互通信。HTTP是现代全球因特网中使用的公共语言。
每天都有数亿JPEG图片、HTML页面、文本文件、MPEG电影、WAV音频文件、java小程序和其他资源在因特网游弋。HTTP可以从全世界的Web服务器上将这些信息迅速、便捷、可靠的传输到Web浏览器上。
HTTP使用的是可靠的数据传输协议,它能够确保数据在传输过程中不会被损坏或者产生混乱。对开发人员来说,无需担心HTTP通信会在传输过程中被破坏、复制或者产生畸变。开发人员可以专注于程序特有细节的编写,而不是考虑因特网中存在的一些缺陷和问题。
Web内容都是存储在Web服务器上。Web服务器使用HTTP协议,因此还可以称为HTTP服务器。HTTP客户端向服务器发出请求,服务器会在HTTP响应中回送所请求的数据。
最常见的HTTP客户端就是浏览器。浏览器向服务器请求HTTP对象,并将对象显示在屏幕上。
因特网有很多的数据类型,HTTP给每种要通过Web传输的对象都打上MIME类型(MIME type)的数据格式标签。最初设计MIME(Multipurpose Internet Mail Extension,多用途因特网邮件扩展)是为了解决不同电子邮件系统之家搬移报文时存在的问题。
Web服务器会为所有的HTTP对象数据附一个MIME类型。当Web浏览器从服务器取回一个对象时,会去查看相关的MIME类型,看看它是否知道应该如何处理这个对象。大多数浏览器都可以处理上百种常见对象:显示图片、解析并格式化HTML文件、播放音频文件、或者运行外部软件来处理特殊格式数据。
MIME类型是一种文本标记,表示一种主要的对象类型和一个特定的子类型,中间由一条斜杠来分隔。
例如:HTML格式的文本文档 text/html类型来标记。
每个Web服务器都有一个名字,这样客户端就可以说明它们感兴趣的资源是什么。服务器资源名被统一称为统一资源标识符(Uniform Resource Identifier,URI)。URI有两种形式:分别是URL和URN。
URI的第二种形式就是URN(统一资源名)。URN是作为特定内容的唯一名称使用的,与目前的资源所在地无关。使用这些与>位置无关的URN,就可以将资源四处搬动。通过URN,还可以用同一个名字通过多种网络访问协议来访问资源。
URN仍然处于试验阶段,还未大范围使用。除非特殊说明,否则这里的都是用URL来指定URI。
一个HTTP事务由一条请求命令和一个响应结果组成。这种通信通过名为HTTP报文(HTTP message)的格式化数据块进行。
HTTP支持几种几种不同的请求命令,这些命令被称为HTTP方法(HTTP method)。每条HTTP请求报文都包含一个方法。这个方法会告诉服务器要执行什么动作(获取一个Web页面、运行一个网关程序、删除一个文件等)。
常见的HTTP方法:
HTTP方法 | 描述 |
---|---|
GET | 从服务器向客户端发送命名资源 |
PUT | 将来自客户端的数据存储到一个命名的资源服务器中 |
DELETE | 从服务器中删除命名资源 |
POST | 将客户端数据发送到一个服务器网关应用程序 |
HEAD | 仅发送命名资源响应中的HTTP首部 |
- 状态码
每条HTTP响应报文返回时都会携带一个状态码。状态码是一个三位数字的代码,告知客户端请求是否成功,或者是否需要采取其他动作。
常见的HTTP状态码:
HTTP状态码 | 描述 |
---|---|
200 | OK, 文档正确返回 |
302 | Redirect(重定向)。到其他地方去获取资源 |
404 | Not Found(没找到),无法找到这个资源 |
- Web页面可以包含多个对象
应用程序完成一项任务时通常会发布多个HTTP事务。比如,Web浏览器会发布一系列的HTTP事务来获取并显示一个包含丰富图片的Web页面。浏览器会执行一个事务来获取描述页面布局的HTML”框架“,然后发布另外的HTTP事务来获取每个嵌入式图片、图像面板、Java小程序等。这些嵌入式资源甚至可能位于不同的服务器。因此,一个Web页面通常并不是单个资源,而是一组资源的集合。
HTTP报文都是由一行行的简单字符串组成。HTTP报文都是纯文本,不是二进制代码。
从Web客户端发往Web服务器的HTTP报文称为请求报文(request message)。从服务器发往客户端的报文称为响应报文(reponse message),此外没有其他类型的HTTP报文。请求报文和响应报文格式类似。
HTTP报文包括以下三部分:
报文的第一行就是起始行,在请求报文中用来说明要做些什么,在响应报文中说明出现了什么情况。
起始行后面有0个或者多个首部字段。每个字段都包含一个名字和一个值,为了便于解析,两者之间用冒号(:)分隔。首部以一个空行结束。添加一个首部字段和添加新行一样简单。
空行之后就是可选的报文主体了,其中包含了所有类型的数据。请求主体中包括了要发给Web服务器的数据,响应主体中装载了要返回给客户端的数据。起始行和首部都是文本形式且都是结构化的,而主体则不同,主体可以包含任意的二进制数据(图片、视频、音频、软件程序)。当然,主体还可以包含文本。
HTTP是个应用层协议。HTTP无需关心网络通信的具体细节;它把联网的细节都给了通用、可靠的因特网传输协议TCP/IP。
TCP提供了:
- 无差错的数据传输。
- 按序传输(数据总是按照发送的顺序到达);
- 分段的数据流(可以在任意时刻以任意大小将数据发送出去)。
因特网自身是基于TCP/IP的,它是全世界计算机网络常用的层次化分组交换网络协议集。TCP/IP 隐藏了各种网络和硬件的特点及弱点,使各种类型的计算机和网络都能够进行可靠地通信。
只要建立了TCP连接,客户端和服务器之间的报文交换就不会丢失、被破坏、也不会出现接收时乱序。HTTP协议位于TCP的上层。HTTP使用TCP来传输其报文数据。
在HTTP客户端向服务器发送报文之前,需要用网际协议(Internet Prococol,IP)地址和端口号在客户端和服务器之间建立一条TCP/IP连接。
建立一条TCP连接的过程与给公司办公室的某个人打电话的过程类似。首先,要拨打公司的电话号码。这样就能进入正确的机构了。其次,拨打要联系的那个人的分机号。
最初怎么获取服务器的IP地址呢?当然是通过URL。
先看几个URL:
http://207.200.83.29:80/index.html
http://www.netscape.com:80/index.html
http://www.netscape.com/index.html
第一个 URL 使用了机器的 IP 地址,207.200.83.29 以及端口.第二个 URL 没有使用数字形式的 IP 地址,它使用的是文本形式的域名,或者称为主机名(www.netscape.com) 。主机名就是 IP 地址比较人性化的别称。可以通过一
种称为域名服务(Domain Name Service,DNS)的机制方便地将主机名转换为 IP地址,这样所有问题就都解决了。
最后一个 URL 没有端口号。HTTP 的 URL 中没有端口号时,可以假设默认端口号是 80。有了 IP 地址和端口号,客户端就可以很方便地通过 TCP/IP 进行通信了。
在HTTP客户端向服务器发送报文之前,需要用网际协议(Internet Prococol,IP)地址和端口号在客户端和服务器之间建立一条TCP/IP连接。
建立一条TCP连接的过程与给公司办公室的某个人打电话的过程类似。首先,要拨打公司的电话号码。这样就能进入正确的机构了。其次,拨打要联系的那个人的分机号。
最初怎么获取服务器的IP地址呢?当然是通过URL。
先看几个URL:
http://207.200.83.29:80/index.html
http://www.netscape.com:80/index.html
http://www.netscape.com/index.html
第一个 URL 使用了机器的 IP 地址,207.200.83.29 以及端口.第二个 URL 没有使用数字形式的 IP 地址,它使用的是文本形式的域名,或者称为主机名(www.netscape.com) 。主机名就是 IP 地址比较人性化的别称。可以通过一
种称为域名服务(Domain Name Service,DNS)的机制方便地将主机名转换为 IP地址,这样所有问题就都解决了。
最后一个 URL 没有端口号。HTTP 的 URL 中没有端口号时,可以假设默认端口号是 80。有了 IP 地址和端口号,客户端就可以很方便地通过 TCP/IP 进行通信了。
步骤如下:
(a) 浏览器从 URL 中解析出服务器的主机名;
(b) 浏览器将服务器的主机名转换成服务器的 IP 地址;
(c) 浏览器将端口号(如果有的话)从 URL 中解析出来;
(d) 浏览器建立一条与 Web 服务器的 TCP 连接;
(e) 浏览器向服务器发送一条 HTTP 请求报文;
(f) 服务器向浏览器回送一条 HTTP 响应报文;
(g) 关闭连接,浏览器显示文档。
Telnet程序可以将键盘连接到某个目标TCP端口,并将此TCP端口的输出回送到显示屏上。Telnet常用于远程终端会话,但它几乎可以连接所有的TCP服务器,包括HTTP服务器。
可以通过Telnet程序直接与Web服务器进行对话。通过Telnet可以打开一条到某台机器上某个端口的TCP连接,然后直接向端口输入一些字符。Web服务器会将Telnet程序作为一个Web客户端来处理,然后回送给TCP连接的数据会显示在屏幕上。
实际例子:Telnet获取URL http://www.joes-hardware.com:80/tools.html 所指向的文档
HTTP 的 1991 原型版本称为 HTTP/0.9。这个协议有很多严重的设计缺陷,只应该用于与老客户端的交互。HTTP/0.9 只支持 GET 方法,不支持多媒体内容的MIME 类型、各种 HTTP 首部,或者版本号。HTTP/0.9 定义的初衷是为了获取简单的 HTML 对象,它很快就被 HTTP/1.0 取代了。
1.0 是第一个得到广泛使用的 HTTP 版本。HTTP/1.0 添加了版本号、各种 HTTP首部、一些额外的方法,以及对多媒体对象的处理。HTTP/1.0 使得包含生动图片的 Web 页面和交互式表格成为可能,而这些页面和表格促使万维网为人们广泛地接受。这个规范从未得到良好地说明。在这个 HTTP 协议的商业演进和学术研究都在快速进行的时代,它集合了一系列的最佳实践。
在 20 世纪 90 年代中叶,很多流行的 Web 客户端和服务器都在飞快地向 HTTP中添加各种特性,以满足快速扩张且在商业上十分成功的万维网的需要。其中很多特性,包括持久的 keep-alive 连接、虚拟主机支持,以及代理连接支持都被加入到 HTTP 之中,并成为非官方的事实标准。这种非正式的 HTTP 扩展版本通常称为 HTTP/1.0+。
HTTP/1.1 重点关注的是校正 HTTP 设计中的结构性缺陷,明确语义,引入重要的性能优化措施,并删除一些不好的特性。HTTP/1.1 还包含了对 20 世纪 90 年代末正在发展中的更复杂的 Web 应用程序和部署方式的支持。HTTP/1.1 是当前使用的 HTTP 版本。
HTTP-NG 是 HTTP/1.1 后继结构的原型建议,它重点关注的是性能的大幅优化,以及更强大的服务逻辑远程执行框架。HTTP-NG 的研究工作终止于 1998 年,编写本书时,还没有任何要用此建议取代 HTTP/1.1 的推广计划。
前面重点介绍了Web应用程序(Web客户端和Web服务器)是如何相互发送报文来实现基本事务处理的。因特网上还有一些其他的应用程序。下面一一介绍。
代理位于客户端和服务器之间的HTTP中间实体。接收所有客户端的 HTTP 请求,并将这些请求转发给服务器(可能会对请求进行修改之后转发) 。对用户来说,这些应用程序就是一个代理,代表用户访问服务器。
出于安全考虑,通常会将代理作为转发所有 Web 流量的可信任中间节点使用。代理还可以对请求和响应进行过滤。比如,在企业中对下载的应用程序进行病毒检测,或者对小学生屏蔽一些成人才能看的内容。
Web 缓存(Web cache)或代理缓存(proxy cache)是一种特殊的 HTTP 代理服务器,可以将经过代理传送的常用文档复制保存起来。下一个请求同一文档的客户端就可以享受缓存的私有副本所提供的服务了.
网关(gateway)是一种特殊的服务器,作为其他服务器的中间实体使用。通常用于将 HTTP 流量转换成其他的协议。网关接受请求时就好像自己是资源的源端服务器一样。客户端可能并不知道自己正在与一个网关进行通信。
例如,一个 HTTP/FTP 网关会通过 HTTP 请求接收对 FTP URI 的请求,但通过 FTP协议来获取文档 。得到的文档会被封装成一条 HTTP 报文,发送给客户端。第 8 章将探讨网关。
隧道(tunnel)是建立起来之后,就会在两条连接之间对原始数据进行盲转发的HTTP 应用程序。HTTP 隧道通常用来在一条或多条 HTTP 连接上转发非 HTTP 数据,转发时不会窥探数据。
HTTP 隧道的一种常见用途是通过 HTTP 连接承载加密的安全套接字层(SSL,Secure Sockets Layer)流量,这样 SSL 流量就可以穿过只允许 Web 流量通过的防火墙了。如图所示,HTTP/SSL 隧道收到一条 HTTP 请求,要求建立一条到目的地址和端口的输出连接,然后在 HTTP 信道上通过隧道传输加密的 SSL 流量,这样就可以将其盲转发到目的服务器上去了。
用户 Agent 代理(或者简称为 Agent 代理)是代表用户发起 HTTP 请求的客户端程序。所有发布 Web 请求的应用程序都是 HTTP Agent 代理。到目前为止,我们只提到过一种 HTTP Agent 代理:Web 浏览器,但用户 Agent 代理还有很多其他类型。用fiddler抓包找头部信息会发现类似User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
比如,有些自己会在 Web 上闲逛的自动用户 Agent 代理,可以在无人监视的情况下发布 HTTP 事务并获取内容。这些自动代理的名字通常都很生动,比如“网络蜘蛛”(spiders)或者“Web 机器人” (Web robots) 。网络蜘蛛会在 Web 上闲逛,搜集信息以构建有效的 Web 内容档案,比如一个搜索引擎的数据库或者为比较购物机器人生成的产品目录。
URL是浏览器寻找信息所需的资源位置。URI是一类更通用的资源标识符,URL是URI的一个子集。URI包括URL和URN。
:// : @:/ ;?#
http://www.joes-hardware.com/hammers;sale=false/index.html;graphic=ture
这个例子就有两个路径段,hammers和index.html。hammers路径段的参数是sale,值为false。index.html段有参数graphics,值为true。
http://www.joes-hardware.com/inventory-check.cgi?item=12731
问号右边的内容称为查询组件。URL的查询组件和标志网关资源的URL路径组件一起被发送给网关资源。基本上可以将网关当作访问其他应用程序的访问点。
HTTP服务器只处理整个对象,而不是对象的片段,客户端不能将片段传送给服务器,浏览器获得整个资源后,会根据片段来显示你感兴趣的内容。
首先我们先来了解TCP报文段
重要的标志我在图中也有标记,重点了解标志位
ACK:确认序号有效
RST:重置连接
SYN:发起了一个新连接
FIN:释放一个连接
简单来说,就是
1. 建立连接时,客户端发送SYN包(SYN=i)到服务器,并进入到SYN-SEND状态,等待服务器确认
2. 服务器收到SYN包,必须确认客户的SYN(ack=i+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器进入SYN-RECV状态
3. 客户端收到服务器的SYN+ACK包,向服务器发送确认报ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手
在此穿插一个知识点就是SYN攻击,那么什么是SYN攻击?发生的条件是什么?怎么避免?
在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是 Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址 是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网 络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:
#netstat -nap | grep SYN_RECV
由于TCP连接时是全双工的,因此每个方向都必须单独进行关闭。这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的链接。收到一个FIN只是意味着这一方向上没有数据流动,既不会在收到数据,但是在这个TCP连接上仍然能够发送数据,知道这一方向也发送了FIN,首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
有人可能会问,为什么连接的时候是三次握手,而断开连接的时候需要四次挥手?
这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN 报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再 发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。
简单来说就是
1. 客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送(报文段4)。
2. 服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。
3. 服务器B关闭与客户端A的连接,发送一个FIN给客户端A(报文段6)。
4. 客户端A发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。
A在进入到TIME-WAIT状态后,并不会马上释放TCP,必须经过时间等待计时器设置的时间2MSL(最长报文段寿命),A才进入到CLOSED状态。为什么?
为了保证A发送的最后一个ACK报文段能够到达B
防止“已失效的连接请求报文段”出现在本连接中
OK~是不是很难懂的感觉?那我们来说的“人性化点的”吧
三次握手流程
1. 客户端发个请求“开门呐,我要进来”给服务器
2. 服务器发个“进来吧,我去给你开门”给客户端
3. 客户端有很客气的发个“谢谢,我要进来了”给服务器
四次挥手流程
1. 客户端发个“时间不早了,我要走了”给服务器,等服务器起身送他
2. 服务器听到了,发个“我知道了,那我送你出门吧”给客户端,等客户端走
3. 服务器把门关上后,发个“我关门了”给客户端,然后等客户端走(尼玛~矫情啊)
4. 客户端发个“我知道了,我走了”,之后自己就走了
参考
http://www.cnblogs.com/qcssmd/p/5508150.html
https://blog.csdn.net/u011318165/article/details/48102939