HTTP消息格式
Http
协议有两类消息,分别是请求消息(Request
)和响应消息(Response
)。
- 请求消息
请求消息是用ASCII
码写的,人直接可读。
第一行称之为请求行。请求行的第一部分是请求的命令,Get
是一个请求方法,除此之外还有POST
、HEAD
等等都可以。后面跟的是一个URL
,和HTTP
的版本。之后的几行称之为头部行,表明要访问的主机地址(这里都建立起了TCP
连接了,这个地址还有用吗?在缓存的时候有用)。之后是浏览器类型,服务器会依据你的浏览器类型发送符合你的浏览器的版本。Connection
表示发完这个可以把连接关闭了。之后定义为接受的语言。最后为一个回车,空行,表明消息结束了。通用格式如下图所示:
请求消息里面有时候也会带有数据,比如要登陆某个网站的时候,请求消息里面就会带有数据。向服务器中上传数据的方法有两种:
POST
方法:在第一行中可以定义不同的方法,比如举例得到的GET
方法。POST
会将表格中的数据放到消息体(Entity body
)中。然后传给服务器,服务器从这里面讲数据提取出来。Get
方法:我们称这种方法为URL
方法,如果信息比较少的话,我们可以将其放到Request
行的URL
字段中。也就是方法不变,但是在URL
中加一些信息。
- 方法类型:
HTTP 1.0
里面有GET
方法(我们从浏览器中获得的);我们还有POST
方法;还有一个HEAD
方法,请求服务器不要将所请求的对象放入到响应消息中,只是返回头部的一些东西;
HTTP 1.1
又增加了两种方法,分别是PUT
和DELETE
。PUT
是将消息体中的文件上传到URL
字段所指定的路径(此功能支持上传文件)。DELETE
删除URL
字段所指定的文件。
- 响应消息
同样是ASCII
写的,第一行称为状态行(status line
),前面说的是使用的http
版本1.1
,返回的状态是200
,后面跟一个解释OK
。
接下来几行都是头部行(header lines
)。Date
是Web
服务器生成响应消息的时间,Last-Modified
是上次网页的修改时间,是1998
年Jun 22
。Server
表示服务器使用的软件类型。之后再定义了文本的长度和文本类型。
这里要注意这个状态行,方便我们之后上网知道网页出错的原因:
200
代表OK
;301
代表这个网页被永久性的移走了;400
表示Bad Request
;404
表示找不到;505
表示HTTP
版本不支持;
Cookie技术
HTTP
协议是一种无状态的,也就是服务器不记录客户的历史行为。这个时候就可能带来一些问题。比如网上购物,实现购物车等等,很多时候我们需要记录用户的会话。
Cookie
技术是某些网站为了辨别用户身份,进行session
跟踪而存储在用户本地终端上的数据(经常通过加密)。Cookie
的RFC
编号是6265
。
Cookie
是架设在HTTP
上面的一个组件,首先是会在HTTP
响应消息中增加cookie
头部行,Cookie
是后来才发展出来的,所以HTTP
的头部行是可扩展的。请求消息中也会增加Cookie
的头部行。然后在客户端的主机上会有一个Cookie
文件,由浏览器管理。在服务器那头会建立一个后台的数据库。
那有了上述这些组件之后能不能解决无状态的这样一个问题呢?其工作原理如下:
客户端首先用常规的请求消息,不带Cookie
头部向服务器发送消息,服务器一看是新访问的用户,就给它创建一个ID 1678
,然后把ID
号和客户信息放到数据库中去,记录下来。之后在返回的消息中,利用响应消息头部行,加一个Set Cookie 1678
。
然后浏览器收到这一行消息之后,就会把这个行解析出来,在自己的Cookie
文件中增加一行,再次访问的话,就会在常规的访问消息中增加Cookie 1678
。此时服务器那一端就知道了这个用户,可以在数据库中对其资料进行查询,可以做出针对这个用户特定的动作。
所以Cookie
可以用于身份认证、购物车、推荐系统、Web e-mail
等。Cookie
最大的问题就是隐私问题。
这一小节主要理解Cookie
技术、有状态和无状态、以及如何在HTTP
协议基础上如何去扩展新的技术,新的消息,以适应新的需求。
Web缓存技术
缓存,或者称之为Web
服务器表示在不访问服务器的前提下满足客户端的HTTP
请求。说得形象一点是如果学校或者公司有Web
服务器的话,浏览网页可能就是它直接给你的,根本没有去访问目标地址。发明这种技术主要是从性能角度考虑,Cookie
主要是从功能上考虑。
Web
服务器能够缩短客户请求的响应时间;减少机构/组织的流量;在大范围内(Internet
)实现有效的内容分发。
结构如上图所示,实际上就是在客户和服务器之间架设了一个代理服务器。架设完它之后,用户在访问Web
的时候都访问这个代理服务器,而不是访问原始服务器。
如果所请求的对象在缓存服务器中有,缓存返回对象,否则,缓存服务器向原始服务器发送HTTP
请求,获取对象,然后返回给客户端并保存该对象。缓存既充当客户端,也充当服务器,一般由ISP
(Internet服务提供商)架设。
- 条件性GET方法
HTTP
请求中有一个Last Modified
。条件性GET
的基本思想是,如果缓存有最新的版本,则不需要发送请求对象。在HTTP
请求消息中声明所持有版本的日期。如果服务器那端收到条件性GET
方法的时候,如果缓存的版本是最新的,则响应消息中不包含对象。
Email应用
Email
由以下几部分构成:
- 邮件客户端(
User Agent
):主要负责读、写Email
消息,能够与服务器进行交互,收发Email
。当使用浏览器的时候,浏览器本质上也是一种Web
客户端。 - 邮件服务器:邮件服务器是
Email
的核心。用户向邮件服务器申请账号,之后服务器给用户开辟一个账号。当我们不在线的时候,收到的邮件存在邮件服务器中。邮件服务器中还会创建一个消息队列,存储我们要发送出去的邮件,然后会代替我们的PC
机,确保将邮件发送到指定的地方。 - SMTP协议(
Simple Mail Transfer Protocol
,简单邮件传输协议):它是邮件服务器之间传输消息所使用的协议,传输过程中,客户端是发送消息的服务器,服务器是接收消息的服务器。
为什么我们需要邮件服务器?为什么我们需要这样一种架构?采用邮件服务器的好处在于:手机或者客户端不能保证7*24
小时在线,邮件服务器就能确保邮件一直能够接收到。
SMTP
是email
应用的核心协议,可以参考RFC 2821
。因为需要确保消息的可靠传输,所以需要使用TCP
进行网络网络传输。它运行在25
号端口上面,传输过程一般要经历三个阶段:握手、消息的传输、关闭。他采用的是一种命令/响应的交互模式(HTTP
采用的是请求/响应的模式)。命令也是采用可读的模式(ASCII
文本),响应采用状态代码和语句的方式。由于Email
比较古老,只有文本,没有多媒体,所以Email
消息里面只能包含7
位ASCII
码。
Email
应用是一个典型的异步应用,发送方和接收方不需要同时。这种方式是很方便的。在这背后SMTP
协议是如何工作的?
- SMTP协议交互示例
SMTP
的命令和响应统统是用ASCII
码构成的,我们可以直接阅读交互过程:
建立TCP
连接之后,服务器发送域名,要发邮件的服务器发送hello
先打个招呼,等等交互信息:
与HTTP
协议进行一个对比:
HTTP
是一个拉式的网络应用,需要从Web
服务器将网页拉回本地。而SMTP
是一种推式的这样一个协议,由发送方主动地建立连接,然后把消息推送到接收方,它们都是用了一种命令响应的交互模式,或者说是请求响应的交互模式,命令和状态代码都是ASCII
。HTTP是每个对象封装在独立的响应消息中,SMTP是多个对象在由多个部分构成的消息中发送。
Email消息格式与pop协议
Email
应用由邮件客户端、邮件服务器、SMTP
协议三大部分构成。那SMTP
传输的Email
消息格式是什么样子的呢?由两部分构成:
- 消息头部行:
Http
协议里面也有消息的头部行,头部行里面有to
、from
、subject
字段(发件人,收件人,邮件标题),它与SMTP
命令不同。 - 消息体:真正的内容在消息体中,只支持
ASCII
字符。二进制构成的、非ASCII
字符的文件,通过多媒体邮件扩展(MIME
)进行传输。通过在邮件头部增加额外的行以声明MIME的内容类型。声明邮件里面有多媒体内容、采用的编码格式等内容。
Email
遵循SMTP
的简单邮件传输协议,从服务器获取邮件的协议称为邮件访问协议。典型的为POP
协议。这里使用了多个协议,是Email
应用和Web
应用一个很大的不同。
1. POP
(Post Office Protocol
,邮局协议):两个阶段:1. 认证/授权阶段,确保是邮件的拥有者,另外是从邮件服务器下载邮件。2. 另外一个协议为IMAP
(Internet Mail Access Protocol
)协议,是一个比POP3
更新的协议,其有更多的功能,实现起来也更加复杂。3. 第三类有HTTP
协议:163
、QQ Mail
。基于Web
应用里面的。
POP3
协议有几个阶段:
- 认证阶段,采用的是命令、响应的一种模式。客户端命令:
User
声明用户名,Pass
声明密码。基于此服务器端会给出OK
,或者Error
响应。 - 事务阶段:
List
列出消息数量;Retr
用编号获取消息;Dele
删除消息;Quit
可以退出。
POP3
协议有几种模式:
- 下载并删除模式:在这个模式下,用户如果换了客户端软件,则无法重读该邮件;
- 下载并保持模式:不同客户端都可以保留消息的拷贝。
POP3
也是一个无状态的协议。
IMAP
协议相比于POP3
协议有很大的进步:1. 所有消息统一保存在一个地方:服务器。2. 允许用户利用文件夹组织消息;3. IMAP
支持跨会话(Session
)的用户状态,所以在服务器上建立文件夹,把消息放入文件夹中,之后在所有的客户端上都是一致的。所以说IMAP
是一个有状态的协议。
DNS应用
DNS概述
DNS
(Domain Name System)互联网上的一个核心服务,是一个庞大的应用。它解决的是互联网上的主机/路由器的识别问题。每个主机需要IP
地址来辨识,IPV4
版本是一组32
位的数,IPV6
版本是128
的。IP
地址本身是数字,对人类并不友好,所以日常生活中上网使用的是一些域名:www.csdn.com
。采用这种方式就需要解决域名和IP
地址之间的映射问题。负责做这个映射的系统就是DNS
,也称作域名解析系统。
它是多层命名服务器构成的分布式数据库,能够将域名翻译成IP
地址。它本身也是一个应用层协议,在应用层协议之上又有应用层软件,负责完成名字的解析。它所提供的服务是互联网的核心功能,但是用应用层协议实现。(为什么在应用层做呢?)
DNS
最基本的服务是域名向IP
地址的翻译;还有别名的服务,将不好记的名字变成一个好记的名字;邮件服务器的别名也可以做到;另外还可以做负载均衡,当域名向IP
地址翻译的时候可以提供多个映射,没有新的服务的时候还可以调整地址的顺序。
- 为什么不采用集中式的
DNS
?
如果采用集中式的可能会遇到如下问题:1. 单点失败问题:如果我们使用集中式的服务器,一旦服务点坏掉了,整个互联网就坏掉了。2. 流量问题:几十亿台主机请求DNS
的流量太大。3. 距离问题:不知道放在那里,时延严重;4. 维护性问题。
集中式的DNS
是不可伸缩的。所以DNS
采用的是分布式的层次式的数据库,这个服务器分布在全世界。
根服务器->顶级域名服务器->公司/学校的域名服务器。
如果客户端想要查询www.amazon.com
的IP
。客户端查询根服务器,找到com
域名解析服务器;客户端查询com
域名解析服务器,找到amazon.com
域名解析服务器,客户端查询amazon.com
域名解析服务器,获得www.amazon.com
的IP
地址。
但是分布式的也有代价,这里为了获得域名的查询,这里查询了三次。
- 根域名服务器:本地域名无法解析服务器时,就需要访问根域名服务器。如果根域名服务器知道,就直接给出;不知道的话就访问权威域名服务器,获得映射,向本地域名服务器返回映射。
- 顶级域名服务器(
TLD
,Top-Level Domain
):负责com
,org
,net
,edu
等顶级域名和国家顶级域名,例如cn
,uk
,fr
等。这些顶级域名服务器由一些组织来维护,比如Network Solution
维护com
顶级域名服务器,Educause
维护edu
顶级域名服务器。 - 权威(Authoritative)域名服务器:组织的域名解析服务器,提供组织内部服务器的解析服务。由组织负责维护,或者委托提供商负责维护。
- 本地域名解析服务器:它并不严格属于层级体系,每个
ISP
有一个本地域名服务器,也称为默认域名解析服务器。当主机进行DNS
查询时,查询被发送到本地域名服务器,然后本地域名服务器作为一个代理(proxy
),将查询转发给(层级式)域名解析服务器系统。
只要域名解析服务器获得了IP
地址映射,他就要进行缓存。(一段时间过后,缓存条目失效)。本地域名服务器一般会缓存顶级域名服务器的映射,所以根域名服务器不经常被访问。
DNS记录和消息
DNS
依赖的是一个分布式的,层次式的数据库。数据库中存的数据的格式是什么样子的呢?
DNS
里面的记录,我们也称作资源记录(Resource Records
RR
),是一个四元组(name value type ttl
(关于时间有效性的一个字段))。不同类型中name
和value
的解释是不一样的。1. Type A
:name
是主机的类型,value
是主机的IP
地址;2. Type NS
:nam
e是域(edu.cn
),value
是该域权威名解释服务器的主机域名。也就是指出了这个域的域名解析服务器是谁;3. Type CNAME
:用于实现DNS
的别名服务,name
是某一真实域名的别名,value
是真实域名;4. Type MX
:这个是专门用来邮件服务器的,所以这个value
是与name
相对应的邮件服务器。
DNS
是一个网络应用,自然也有它的协议,是一种查询(query
)和回复(reply
)性的协议。自然就会有查询回复的消息,这两种消息的格式是一样的。
它有消息的头部,identification
,是一个16
位的查询编码,回复使用相同的编号,这样就能够区分是哪一个查询的回复;flags
字段是一些标志位,标识这个消息是一个查询消息还是回复消息,期望是一个递归吗?这个递归是否可用?这是否是一个权威回答等等。
- 如何注册域名?
在域名管理机构(如Network Solutions
)注册域名(netXXX.com
),具体的,需要向域名管理机构提供你的权威域名解析服务器的名字和IP
地址,域名管理机构向com
顶级域名解析服务器中插入两条记录。
如果这个时候办了一个自己的邮件服务器,这个时候还需要在权威域名解析服务器中为www.netXXX.com
中加入Type A
记录,为net.XXX.com
加入Type MX
记录。
- 如果能上QQ,上不了网页,是因为解析不了域名,也就是DNS相关出了问题。
- 如果本地域名服务无缓存,当采用递归方法解析另一网络某主机域名时,用户主机 、 本地域名服务器发送的域名请求消息数分别为多少?
域名的解析过程分为两种情况:递归查询和迭代查询:
- 递归查询:客户机发送一条查询请求到本地域名服务器,发现缓存中没有主机名和
IP
地址对的信息,那么本地域名服务器就往上继续查询,发送一个查询报文,如果在某一级域名服务器找到了主机名和IP
地址对信息,就直接返回。如果找不到,那么这个域名服务器又会作为客户机去请求上一级域名服务器,直至根域名服务器,根名称服务器收到DNS
请求后,把所查询得到的所请求的DNS
域名中发送给顶级域名服务器,让顶级域名服务器去往下级域名服务器请求查找,如果找到了就原路返回。某域名服务器-->...->顶级域名服务器-->根域名服务器-->下一级域名服务器-->...-->本地域名服务器-->客户机
。 - 迭代查询:当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所查询的
IP
地址,要么告诉本地域名服务器:“下一步应当向哪个域名服务器进行后续查询”,然后由本地域名服务器进行后续查询。然后,本地域名服务器查询多次。
所以如果是采用递归查询的话,用户主机和本地域名服务器发送的域名请求消息都为1
次,如果是迭代查询的话,用户主机发送的请求消息为1
次,但是本地域名服务器发送的域名请求消息为多次。
P2P应用
Web
应用、Email
应用、DNS
应用主要都是C/S
架构。这一小节主要介绍P2P
架构。
P2P
(Peer-to-Peer
)没有服务器,没有7*24
小时一直等待的服务器;任意端系统之间可以直接通信,P2P
架构有很大的动态和随机性,节点具有随机性,也有可能动态更换IP
地址等等。它的一个很重要的缺点就是,比较复杂,难以管理。
首先我们对P2P
和客户机/服务器文件分发对比:
- 索引技术
P2P
中经常会需要搜索信息,索引是信息到节点位置(IP
地址+端口号)的映射。比如文件共享中,我们需要利用索引动态跟踪节点所共享的文件位置,节点需要告诉索引它拥有哪些文件,节点搜索索引,从而获知能够得到哪些文件。
在即时消息中,索引负责将用户名映射到位置,当用户开启IM应用时,需要通知索引它的位置,节点检索索引,确定用户的IP地址。
那索引如何来设计呢?
- 集中式索引:在
Napster
中最早采用这种设计,任何节点加入时,都需要通知中央服务器它的IP地址,和它所持有的内容,当某一个节点需要查找时,只需要向中央服务器查找就可以了。找到之后直接就向另外的节点请求获取文件即可。
在集中式索引中,虽然内容和文件传输是分布式的,但是内容定位是高度集中式的,就会面临单点失效问题、并且这种集中式的会成为性能的瓶颈。
- 分布式索引系统:洪泛查询(
Query flooding
),这个架构师完全的分布式架构,没有任何特殊的节点,每个节点负责对自己共享的文件进行索引,并且只索引自己的。那如何获取全局信息呢?
采用覆盖网络的方式进行检索,所谓的覆盖网络说的是:如果节点X XX与Y YY之间有TCP
连接,那么构成一个边,所有的活动节点和边构成覆盖网络,边为虚拟链路。
查询消息的时候通过已有的TCP
连接去发送,任何收到查询消息的节点都继续转发这个查询消息。如果查询命中的话,则利用反向路径发回查询节点。
- 层次式覆盖网络:它是介于集中式索引和洪泛查询之间的一种方法,节点分为两种,普通节点和超级节点,节点和超级节点之间维持
TCP
连接,某些超级节点对之间维持TCP
连接。
超级节点负责跟踪子节点的内容。