- 计算机网络的应用层
这是计算机网络连载系列的第三篇文章,前两篇文章见
在介绍完计算机基础知识和 TCP/IP 协议簇的基础概念之后,相信读者对计算机网络有了初步的认识,那么下面我们就要对不同的协议层进行分类介绍了,我们选用从应用层产生数据开始,逐步下探至数据链路层,因为这种介绍对读者来说更容易接纳,吸收程度更好。
一般情况下,用户不会在意网络应用程序是按照怎样的机制运行的,用户也不会关心它们是如何产生数据的,如何经过协议栈层层包装把数据发出去的,但是我们是程序员,必须要了解它的内部机制。
应用层位于 TCP/IP 模型的最上层,同时应用层也对应 OSI 标准模型的第 5、6、7层,也就是会话层、表现层、应用层。
现如今,越来越多的应用程序通过计算机网络实现相互通信,这些应用包括 Web 浏览器、远程登录、电子邮件、文件传输、文件下载等,而这些应用的日常使用势必要遵循某种协议和规范,应用层协议正是进行这些行为活动的规则和标准。
简单来说,应用层就是规定应用程序在进行通信时所遵循的协议。
应用层协议定义了在不同端系统上应用程序是如何相互传输报文的。一般来说,应用层协议会规定如下内容:
- 交换的报文类型:交换的是请求报文还是响应报文。
- 报文字段的解释:对报文中各个字段的详细描述。
- 报文字段的语义:报文各个字段的含义是什么。
- 报文交换时间、方式:程序何时、以什么方式发送报文以及响应。
直白一点来说,应用层只是产生和使用数据的逻辑层,在这一层次我们并不会关心它们是如何发送数据的以及数据发到哪里。应用层有两种层次结构:
应用层体系结构定义了应用层端系统之间数据交换的方式,一般来说,主流的体系结构有两种:
- 客户-服务器体系结构 - CS 结构 (client-server architecture)
- 对等体系结构 - P2P 结构 (P2P architecture)
在客户-服务器体系结构中,分为请求方和服务方。有一个总是打开的主机称为服务端 (Server)
,它向客户端 (client)
提供服务。客户端会发送请求给服务端,服务端会根据客户端的请求做出响应。举一个简单的例子:我今天下馆子去,找到了一个饭店,这时候会有一个服务员热情接见我,我看完菜单给服务员说我想吃猪肉,这个"我想吃猪肉"就是请求,然后服务员报以热情的微笑并扇了我一巴掌,说:"我们这是清真馆",这个服务员对我笑并扇了我一巴掌然后对我说了句话,就是响应。
我们最常见的服务端就是 Web 服务器,Web 服务器提供于来自浏览器的请求。我们日常访问百度、谷歌,其实就是在访问它们的 Web 服务器。
一般常见的 Web 服务器主要有Apache、IIS、Jboss、Tomcat、WebSphere、WebLogic 等。
当 Web 服务器通过浏览器接收到用户请求后,它会经过一系列的处理把信息或者页面等通过浏览器呈现给用户,这种模式就是客户 - 服务器模式。
这里有两点需要注意
- 在客户 - 服务器模式下,通常客户端彼此之间是并不互相通信的。
- 服务器通常具有固定的、周知的 IP 地址可以提供访问。
客户 - 服务器模式通常会出现随着客户数量的急剧增加导致单台服务器无法满足大量请求的情况。为此,通常需要配备大量的数据中心 (data center)
,用来跟踪所有的用户请求。
与此相反,P2P 对等体系结构对这种数据中心的依赖性很低,因为在 P2P 体系结构中,应用程序在两个主机之间直接通信,这些主机被称为对等方,与有中心服务器的中央网络系统不同,对等网络的每个用户端既是一个请求方也是一个服务提供方。常见的 P2P 体系结构的应用有文件共享、视频会议、网络电话等。举个例子:毕业了很多大学生都有许多个人物品来不及处理,这时候大家会搞一个跳蚤市场,来彼此出售、交换一些个人物品,这里面每个人既是请求方,同时也是服务提供方。
说到跳蚤市场,啰嗦两句,一般这种跳蚤市场有很多好东西,好用不贵,而且卖的东西种类繁多,物品齐全,性价比贼高,懂得都懂。
P2P 一个最大的特点就是扩展性 (self-scalability)
,因为 P2P 网络的一个重要的目标就是让所有的客户端都能提供资源、获取资源,共享带宽,存储空间等。因此,当有更多节点加入且对系统请求增多,整个系统的容量也增大。这是具有一组固定服务器的客户 - 服务器结构不具备的,这也就是 P2P 的优势。
在了解完上述这两种结构之后,我们把关注点放在这两种体系结构下,各个端系统之间是如何进行通信的。
我们上面说到了两种体系结构,一种是客户 - 服务器 CS 模式,一种是 P2P 对等模式。我们都知道一个计算机允许同时运行多个应用程序,在我们看起来这些应用程序好像是同时运行的,那么它们之间是如何通信的呢?
从操作系统的角度上来说,进行通信的实际上是进程 (process)
而不是程序。我们一般所讲的是进程通信,但是没人说程序通信的。进程是一类程序,但是程序并不特指的是进程。一个进程可以被认为是运行在端系统中的程序。当多个进程运行在相同的端系统上时,它们使用进程间的通信机制相互通信。进程间的通信规则由操作系统来确定。
计算机是庞大且繁杂的,计算机网络也是,应用程序不可能只有一个进程组成,它同样是多个进程共同作用协商运行,那么分布在多个端系统之间的进程是如何进行通信的呢?实际上,每个进程中会有一个套接字 (socket)
的,它其实是一个软件接口,套接字也是应用程序的内部接口,应用程序可以通过它发送或接收数据,同时也可以对其进行像对文件一样的打开、读写和关闭等操作。
举个例子来简单类比一下套接字和网络进程:进程可类比一座房子,而它的套接字相当于是房子的门,当一个进程想要与其他进程进行通信时,它会把报文推出门外,然后通过运输设备把报文运输到另外一座房子,通过门进入房子内部,提供给其他进程使用。
下图是一个通过套接字进行通信的示意图。
从上图可以看到,Socket 属于主机或者服务进程的内部接口,由应用程序开发人员进行控制,两台端系统之间进行通信会通过 TCP 缓冲区经由网络传输到另一个端系统的 TCP 缓冲区,Socket 从 TCP 缓冲区读取报文供应用程序内部使用。
套接字是建立网络应用程序的可编程接口,因此套接字也被称为应用程序和网络之间的
应用程序编程接口( Application Programming Interface,API )
。应用程序开发人员可以控制套接字内部细节,但是无法控制运输层的传输,只能对运输层的传输协议进行选择,还可以对运输层的传输参数进行选择,比如最大缓存和最大报文长度等。
关于更多 Socket 的内容,我们会在后面进行讨论。
我们上面提到网络应用程序之间会相互发送报文,那么它是如何知道自己应该向哪个应用进程发送呢?是不是存在某种机制能够让它知道发到哪里?这就好比你要发送电子邮件,你写好了内容但是你不知道给谁发,所以这个时候必须要有一种知道对方地址的机制,并且能够辨明对方唯一的地址,这个地址就是IP 地址。我们会在后面的内容中详细讨论 IP 地址的内容,目前只需要知道 IP 地址是一个 32 比特的数据并且能够唯一标示互联网中任意一台主机的地址就可以了。
只知道 IP 地址是否就可以了呢?当然不行,举个例子:IP 地址就相当于是你在地图上的唯一坐标,比如说是河北省石家庄市xx小区xx栋xx层xx号,可以具体到门牌号,但是你家里可能会有多个人,你到底要给家里的谁发送信息?这个需要明确下,所以上面的门牌号,就相当于是 IP 地址,你要给家里的谁发送消息,这个谁就是端口号。例如,Web 应用程序需要用 80 端口来标示,邮件服务器程序需要使用 25 来标示,这个谁就是 80 或者 25 端口。
我们知道应用程序是按照应用层协议的标准传输数据的,应用程序只是起到一个生产数据和应用数据的程序,那么我们该如何发送报文呢?这就好比你知道目的地是哪里了,你应该选择哪种交通工具?是走路,公交,地铁还是打车?
应用程序发送报文的交通工具的选择也有很多,我们可以从下面这几个方面来进行考量。
- 数据传输是否可靠
分组在计算机网络中会存在丢包问题,丢包问题的严重性和网络协议的性质有关,如果像是电子邮件、文件传输、远程主机、Web 文档传输的过程中出现问题,数据丢失可能会造成非常严重的后果。如果像是网络游戏,多人视频会议造成的影响可能比较小。鉴于此,数据传输的可靠性也是首先需要考虑的问题。因此,如果协议提供了这样的确保数据交付的服务,就认为提供了可靠数据传输,能够忍受数据丢失的应用被称为容忍丢失的应用。
- 吞吐量
吞吐量就是在数据传输过程中,发送进程能够向接收进程交付比特的速率。具有吞吐量要求的应用程序被称为带宽敏感的应用。带宽敏感的应用具有特定的吞吐量要求,而弹性应用能够根据当时可用的带宽或多或少地利用可供使用的吞吐量。
- 定时
定时能够确保网络中两个应用程序的收发能否在指定的时间内完成,这也是应用程序选择运输服务需要考虑的一个因素。比如在游戏中,你一包数据迟迟发送不过去,对面都推塔了你还卡在半路上呢。
- 安全性
最后,选择运输协议一定要能够为应用程序提供一种或多种安全性服务,这个也是非常重要的。
说完运输服务的选型,接下来该聊一聊因特网能够提供哪些服务了。实际上,因特网为应用程序提供了两种运输层的协议,即 UDP
和 TCP
,下面是一些网络应用的选择要求,可以根据需要来选择适合的运输层协议。
应用 | 数据丢失 | 带宽 | 时间敏感 |
---|---|---|---|
文件传输 | 不能丢失 | 弹性 | 不敏感 |
电子邮件 | 不能丢失 | 弹性 | 不敏感 |
Web 文档 | 不能丢失 | 弹性 | 不敏感 |
因特网电话/视频会议 | 容忍丢失 | 弹性 | 敏感,100ms |
流式存储音频/视频 | 容忍丢失 | 弹性 | 敏感,几秒 |
交互式游戏 | 容忍丢失 | 弹性 | 是,100ms |
智能手机消息 | 不能丢失 | 弹性 | 无所谓 |
下面我们就来聊一聊这两种运输协议的应用场景:
TCP 服务模型的特性主要有下面几种:
- 面向连接的服务
在应用层数据报发送后, TCP 会让客户端和服务器互相交换运输层控制信息,交换信息前需要先建立一条连接通道,这个建立连接的过程就是握手。这个握手过程就是提醒客户端和服务器,你们准备好接收数据了吗?握手完成后,一个TCP 连接 (TCP Connection)
就此建立。TCP 连接是一条全双工的,全双工的意思是连接双方的进程都可以在此连接上同时进行收发报文。当应用程序结束报文发送后,必须断开连接。
- 可靠的数据传输
通信进程能够依靠 TCP 无差错、按适当顺序交付所有发送的数据。应用程序能够依靠 TCP 将相同的字节流交付给接收方的套接字,没有字节的丢失和冗余。
- 拥塞控制
当接收方和发送方之间的网络出现拥塞时,TCP 的拥塞控制会抑制发送进程(客户端或服务器),等到网络状态恢复正常后再继续发送。TCP 的拥塞控制并不一定为通信进程带来直接好处,但能为因特网带来整体好处。我们会在后面具体探讨拥塞控制。
UDP 是一种轻量级的传输协议,UDP 是无连接的,因此使用 UDP 协议不需要经过握手过程,直接发就行。UDP 也不会保证报文是否传输到服务端,它就像是一个撒手掌柜。不仅如此,到达接收进程的报文也可能是乱序到达的。但是 UDP 的传输速率非常快,非常适合大多数互联网应用。
下面是上表列出来的一些应用所选择的协议:
应用 | 应用层协议 | 支撑的运输协议 |
---|---|---|
电子邮件 | SMTP | TCP |
远程终端访问 | Telnet | TCP |
Web | HTTP | TCP |
文件传输 | FTP | TCP |
流式多媒体 | HTTP | TCP |
因特网电话 | SIP、RTP | TCP 或 UDP |
下面我们着重介绍一下应用层都有哪些比较重要的应用协议。
万维网 (WWW, World Wide Web)
是将互联网中的信息以超文本的形式展现的系统,用来显示 WWW 结果的客户端被称为 Web 浏览器。通过浏览器,我们无需关注想要访问的内容在哪个服务器上,我们只需要知道我们想访问的内容就可以了。
万维网定义了三个比较重要的概念:
- URI:定义了访问信息的手段和位置
- HTML:定义了信息的表现形式
- HTTP:定义了 WWW 的访问规范
URI (Uniform Resource Identifier)
中文名称是统一资源标识符,使用它就能够唯一地标识互联网上的资源。
URL (Uniform Resource Locator)
中文名称是统一资源定位符,也就是我们俗称的网址,它实际上是 URI 的一个子集。
URI 不仅包括 URL,还包括 URN(统一资源名称),它们之间的关系如下
而且 URI 已经不局限于标识互联网资源,它可以作为所有资源的识别码。
HTML 称为超文本标记语言,是一种标识性的语言。它包括一系列标签.通过这些标签可以将网络上的文档格式统一,使分散的 Internet 资源连接为一个逻辑整体。HTML 文本是由 HTML 命令组成的描述性文本,HTML 命令可以说明文字,图形、动画、声音、表格、链接等。
Web 的应用层协议就是HTTP (HyperText Transfer Protocol, HTTP)
, 超文本传输协议,它是 Web 的核心协议。下面是 HTTP 协议中的几个核心概念。
Web 页面也叫做 Web Page,它是由无数个对象组成,一个对象就是一个文件,这个文件可以是 HTML 文件、一个图片、一段 Java 应用程序等,它们都可以通过 URI 来唯一定位。一个 Web 页面包含了很多对象,Web 页面可以说是对象的集合体。
就如同各大邮箱使用电子邮件传送协议 SMTP 一样,浏览器是使用 HTTP 协议的主要载体,说到浏览器,你能想起来哪几个?随着网景大战结束后,浏览器迅速发展,至今已经出现过的浏览器主要有 IE、Firefox、Chrome、Safari、Opera、Netscape、傲游等。
Web 服务器的正式名称叫做 Web Server,Web 服务器可以向浏览器等 Web 客户端提供文档,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。目前最主流的三个 Web 服务器是 Apache、 Nginx 、IIS。
CDN 是一种内容分发网络,它应用了 HTTP 协议里的缓存和代理技术,代替源站响应客户端的请求。CDN 是构建在现有网络基础之上的网络,它依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN 的关键技术主要有内容存储和分发技术。
打比方说你要去亚马逊上买书,之前你只能通过购物网站购买后从美国发货过海关等重重关卡送到你的家里,现在在中国建立一个亚马逊分基地,你就不用通过美国进行邮寄,从中国就能把书尽快给你送到。
WAF 是一种 Web应用程序防护系统 (Web Application Firewall,简称 WAF),它是一种通过执行一系列针对 HTTP / HTTPS 安全策略来专门为 Web 应用提供保护的一款产品,它是应用层面的防火墙,专门检测 HTTP 流量,是防护 Web 应用的安全技术。
WAF 通常位于 Web 服务器之前,可以阻止如 SQL 注入、跨站脚本等攻击,目前应用较多的一个开源项目是 ModSecurity,它能够完全集成进 Apache 或 Nginx。
WebService 是一种 Web 应用程序,WebService 是一种跨编程语言和跨操作系统平台的远程调用技术。
WebService 是一种由 W3C 定义的应用服务开发规范,使用 client-server 主从架构,通常使用 WSDL 定义服务接口,使用 HTTP 协议传输 XML 或 SOAP 消息,它是一个基于 Web(HTTP)的服务架构技术,既可以运行在内网,也可以在适当保护后运行在外网。
下面我们就来认识一下应用层常见的几个协议,一些我们常用且重要的协议比如 HTTP、DNS 会在后面详细介绍,目前可以作为了解。
HTTP 是一个在网络中专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。HTTP 是一种应用层协议,它使用 TCP 作为运输层协议。
让我们通过一个例子来探讨一下 HTTP 的请求响应过程,我们假设访问的 URL 地址为http://www.someSchool.edu/someDepartment/home.index,当我们输入网址并点击回车时,浏览器内部会进行如下操作
- DNS 服务器会首先进行域名的映射,找到访问 www.someSchool.edu 所在的 IP 地址,然后 HTTP 客户端进程在 80 端口发起一个到服务器 www.someSchool.edu 的 TCP 连接(80 端口是 HTTP 的默认端口)。在客户和服务器进程中都会有一个套接字与其相连。
- HTTP 客户端通过它的套接字向服务器发送一个 HTTP 请求报文。该报文中包含了路径 someDepartment/home.index 的资源(我们后面会详细讨论 HTTP 请求报文)。
- HTTP 服务器通过它的套接字接受该报文,进行请求的解析工作,并从其存储器 ( RAM 或磁盘 ) 中检索出对象 www.someSchool.edu/someDepartment/home.index,然后把检索出来的对象进行封装,封装到 HTTP 响应报文中,并通过套接字向客户进行发送。
- HTTP 服务器随即通知客户端断开 TCP 连接,实际上是需要等到客户接受完响应报文后才会断开 TCP 连接。
- HTTP 客户端接受完响应报文后,TCP 连接关闭。HTTP 客户端从响应体里提取 HTML 响应文件,并检查该 HTML 文件,然后循环检查报文中其他内部对象。
- 检查完成后,HTTP 客户端会通过浏览器渲染把对应的资源通过显示器呈现给用户。
至此,键入网址再按下回车的过程就结束了。上述过程描述的是一种简单的请求-响应全过程,真实的请求-响应情况要比上面描述的过程复杂很多。
从上面整个过程中我们可以总结出 HTTP 进行分组传输是具有以下特征:
- 支持客户 - 服务器模式的问答形式。
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有 GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
- 灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记。
- 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- 无状态:HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
我们上面描述的 HTTP 请求响应过程就是一种非持久性连接,因为每次 TCP 在传递完报文后,都会关闭 TCP 连接,每个 TCP 连接只传输一个请求报文和响应报文。
非持久性连接有一些缺点:
- 首先必须为每个请求的对象建立和维护一个全新的连接。
- 对于每个这样的连接来说,在客户端和服务器中都要分配 TCP 的缓冲区,这无疑给 Web 服务器带来了严重的负担。因为一台 Web 服务器可能要同时服务于数百甚至上千个客户请求。
在采用 HTTP/1.1 持久连接的情况下,服务器在发送响应后会保持该 TCP 连接,后续的请求和响应报文能够通过相同的连接进行传输。如果在一段时间内(可配置)该连接并未再次使用,HTTP 服务器就会断开连接。
我们上面描述了一下 HTTP 的请求响应过程,相信你对 HTTP 有了更深的认识,下面我们就来一起认识一下 HTTP 的报文格式是怎样的。
HTTP 协议主要由三大部分组成:
- 起始行(start line):描述请求或响应的基本信息。
- 头部字段(header):使用 key-value 形式更详细地说明报文。
- 消息正文(entity):实际传输的数据,它不一定是纯文本,可以是图片、视频等二进制数据。
其中起始行和头部字段并成为请求头或者响应头,统称为 Header;消息正文也叫做实体,称为 body。HTTP 协议规定每次发送的报文必须要有 Header,但是可以没有 body,也就是说头信息是必须的,实体信息可以没有。而且在 header 和 body 之间必须要有一个空行(CRLF)。如果用一幅图来表示一下 HTTP 请求的话,我觉得应该是下面这样
如果细化一点的话,那就是下面这样:
这幅图需要注意一下,如果使用 GET 方法,是没有实体体的,如果你使用的是 POST 方法,才会有实体体。当用户提交表单时,HTTP 客户端通常使用 POST 方法;与此相反,HTML 表单的获取通常使用 GET 方法。HEAD 方法类似于 GET 方法,只不过 HEAD 方法不会返回对象。
下面我们来看一下 HTTP 响应报文
可以看到,请求报文和响应报文只有请求头是不同的,其他信息均一致。
请求报文请求行:
GET /some/page.html HTTP/1.1
响应报文:
HTTP/1.1 200 OK
HTTP 协议是一种无状态协议,即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户端的历史请求记录;但是一些网站却需要记住客户信息,比如电商网站客户登录之后选购商品,客户把商品加入购物车之后会跳转到结算页面,这个时候网站需要知道客户信息,如果使用无状态的 HTTP 协议,那么客户根本无法结算。
Session 和 Cookie 的主要目的就是为了弥补 HTTP 的无状态特性。
客户端请求服务端,服务端会为这次请求开辟一块内存空间,这个对象便是 Session 对象,存储结构是一个 Map 映射,具体一点是 ConcurrentHashMap。Session 弥补了 HTTP 无状态特性,服务器可以利用 Session 存储客户端在同一个会话期间的一些操作记录。
服务器第一次接收到请求时,开辟了一块 Session 空间(创建了 Session 对象),同时生成一个 sessionId ,并通过响应头的 Set-Cookie:JSESSIONID=XXXXXXX 命令,向客户端发送要求设置 Cookie 的响应; 客户端收到响应后,在本机客户端设置了一个 JSESSIONID=XXXXXXX 的 Cookie 信息,该 Cookie 的过期时间为浏览器会话结束;
接下来客户端每次向同一个网站发送请求时,请求头都会带上该 Cookie信息(包含 sessionId ),然后服务器通过读取请求头中的 Cookie 信息,获取名称为 JSESSIONID 的值,得到此次请求的 sessionId。
Session 机制有个缺点,比如 A 服务器存储了 Session,就是做了负载均衡后,假如一段时间内 A 的访问量激增,会转发到 B 进行访问,但是 B 服务器并没有存储 A 的 Session,会导致 Session 的失效。
HTTP 协议中的 Cookie 包括 Web Cookie 和浏览器 Cookie,它是服务器发送到 Web 浏览器的一小块数据。服务器发送到浏览器的 Cookie,浏览器会进行存储,并与下一个请求一起发送到服务器。通常,它用于判断两个请求是否来自于同一个浏览器,例如用户保持登录状态。
HTTP Cookie 机制是 HTTP 协议无状态的一种补充和改良。
Cookie 主要用于下面三个目的
-
会话管理:登陆、购物车、游戏得分或者服务器应该记住的其他内容。
-
个性化:用户偏好、主题或者其他设置。
-
追踪:记录和分析用户行为。
Cookie 曾经用于一般的客户端存储。虽然这是合法的,因为它们是在客户端上存储数据的唯一方法,但如今建议使用现代存储 API。Cookie 随每个请求一起发送,因此它们可能会降低性能(尤其是对于移动数据连接而言)。
当接收到客户端发出的 HTTP 请求时,服务器可以发送带有响应的 Set-Cookie 标头,Cookie 通常由浏览器存储,然后将 Cookie 与 HTTP 标头一同向服务器发出请求。
Set-Cookie HTTP 响应标头将 cookie 从服务器发送到用户代理。下面是一个发送 Cookie 的例子:
此标头告诉客户端存储 Cookie。
现在,随着对服务器的每个新请求,浏览器将使用 Cookie 头将所有以前存储的 Cookie 发送回服务器。
有两种类型的 Cookies,一种是 Session Cookies,一种是 Persistent Cookies,如果 Cookie 不包含到期日期,则将其视为会话 Cookie。会话 Cookie 存储在内存中,永远不会写入磁盘,当浏览器关闭时,此后 Cookie 将永久丢失。如果 Cookie 包含有效期 ,则将其视为持久性 Cookie。在到期指定的日期,Cookie 将从磁盘中删除。
还有一种是 Cookie 的 Secure 和 HttpOnly 标记,下面依次来介绍一下:
上面的示例创建的是会话 Cookie ,会话 Cookie 有个特征,客户端关闭时 Cookie 会删除,因为它没有指定Expires 或 Max-Age 指令。
但是,Web 浏览器可能会使用会话还原,这会使大多数会话 Cookie 保持永久状态,就像从未关闭过浏览器一样。
永久性 Cookie 不会在客户端关闭时过期,而是在特定日期 ( Expires ) 或特定时间长度 ( Max-Age ) 外过期。例如
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
尽管 Cookie 能够简化用户的网络活动,但是 Cookie 的使用存在争议,因为不少人认为它对用户是一种侵权行为。因为结合 Cookie 和用户提供的账户信息,Web 站点可以知道更多关于用户的信息。
Web 缓存 (Web cache) 也叫做代理服务器缓存,它是代表 HTTP 服务器来满足用户需求的网络实体。Web 缓存器有自己的磁盘存储空间,并会在存储空间内保存最近请求过的对象,如下图所示
Web 缓存可以在用户的浏览器中进行配置,一旦配置后,用户首先访问的就不是初始服务器了,需要先访问代理服务器判断请求的对象是否存在,如果代理服务器没有,再由代理服务器来请求初始服务器把对象返回给客户,同时在自己的磁盘空间保存对象。
这里需要注意,客户和初始服务器的架构是客户-服务器模式,而代理服务器不仅能当服务器使用,也可以当作客户端使用。
代理服务器一般由ISP (Internet Service Provider)
,提供。ISP 也就是我们常说的运营商。
那么为什么需要代理服务器的存在呢?相信你看完上面的描述应该能大致猜到它的作用。
- 首先代理服务器可以大大减少对客户请求的响应时间,能够更快给用户响应。
- 其次代理服务器可以减少一个机构接入链路到网络的通信量,降低网络带宽,降低运营商成本。
- 然后代理服务器可以分担初始服务器的压力,改善应用程序的性能。
现在我们知道了 HTTP 是可以传输普通文件、音频、视频的,这些传输的信息统称为 MIME 类型。HTTP 在传输视频的过程中,也会把视频当做一个对象,而一个对象其实就是一个文件,一个文件都在 HTTP 中都可以用 URL 来表示。当用户在看视频时,客户与服务器建立一个 TCP 连接并发送对该 URL 的 GET 请求,然后服务器响应给客户端时,客户端会缓存一定量的字节数据,当数据超过预先设定的门限时,客户应用程序就开始播放视频。
这种方式有一种局限性就是对每个客户端来说,尽管每个客户端可用的带宽量不同,但所有客户端都收到相同的视频编码。这就造成带宽浪费。这就相当我是一个 2M 的网络和 50M 的光纤都能收到相同的视频编码,以几乎相同的等待时间开始播放视频,那么我为什么还要花 50 兆光纤的钱呢?
为了改善这一现象,出现了 HTTP 的 DASH 动态适应流。它的理念是针对不同流量的网络来说,所能够传输的比特数据也不相同。DASH 允许客户使用不同的因特网传输速率可以播放不同编码速率的视频。对于 3G 用户和光纤用户自然会选择以不同的速率传输比特数据,从而最大限度的使用带宽。
随着互联网的接入用户变得越来越多,视频逐渐成为了比特传输的瓶颈和用户的强烈需求。作为一个因特网视频公司,最一开始提供流式服务最直接的方式是建立单一的大规模数据中心。在数据中心内缓存所有视频,并直接从数据中心向世界范围内传播视频。但是这种方式存在三种问题
- 如果客户远离数据中心,那么服务器到客户分组会跨越许多通信链路并且可能通过许多 ISP,这样你的视频播放能快到哪去?
- 每次视频数据都会重新传递给客户端,这样会严重浪费网络带宽,而且视频公司会支付重复的带宽费用
- 单点故障问题,只要视频数据中心宕机或者其他事故,直接导致全球范围内的视频无法播放。
为了应对能够向全世界的用户 24 小时不间断的分发视频,几乎所有的主流视频公司都会使用内容分发网。CDN 管理分布在多个地理位置上的服务器,在每个服务器上缓存各种视频、音频、文件等。
CDN 管理分布在多个地理位置上的服务器,在它的服务器上存储视频副本,并且所有试图将每个用户请求定向到一个提供最好用户体验的 CDN 位置。那么服务器如何选址呢?事实上有两种服务器安置原则:
深入
:它的主要目标是靠近用户,通过减少端用户和 CDN 集群之间链路和路由器的数量,从而改善了用户感受的时延和吞吐量。邀请做客
:这个原则是通过在少量(例如 10 个)关键位置建造大集群来邀请 ISP 来做客,与深入设计原则相比,邀请做客设计通常产生较低的维护和管理开销。
CDN 可以是专用 CDN,即它由内容提供商自己所拥有;另一种 CDN 是 第三方 CDN,它代表多个内容提供商分发内容。下面我们来聊一下 CDN 工作流程,如下图所示:
- 用户想要访问指定网站的内容。
- 用户首先发起对本地 DNS,LDNS 的查询,LDNS 会将请求中继到网站 DNS 服务器,网站的 DNS 服务器会返回给 LDNS 一个网站 CDN 权威服务器的地址。
- LDNS 服务器会发送第二个请求给网站 CDN 权威服务器,希望获取网站内容分发服务器的地址,网站 CDN 会把 CDN 内容分发服务器的地址发送给本地 DNS 服务器。
- 本地 DNS 服务器会把网站 CDN 内容分发服务器的地址发送给用户。
- 用户知道网站 CDN 内容分发服务器的地址后,无需额外操作,直接和网站 CDN 内容分发服务器建立 TCP 连接,并且发出 HTTP GET 请求,如果使用了 DASH 流,会根据不同 URL 的版本选择不同速率的块发送给用户。
任何 CDN 的部署,其核心是集群选择策略 (cluster selection strategy),即动态的将客户定向到 CDN 中某个服务器集群或数据中心的机制。一种简单的策略是指派客户到地理上最为临近 (geographically closest)的集群。这种选择策略忽略了时延和可用带宽随因特网路径时间而变化,总是为特定的客户指派相同的集群;还有一种选择策略是实时测量 (real-time measurement)。该机制是基于集群和客户之间的时延和丢包性能执行周期性检查。
试想一个问题,我们人类可以有多少种识别自己的方式?可以通过身份证来识别,可以通过社保卡号来识别,也可以通过驾驶证来识别,尽管我们有多种识别方式,但在特定的环境下,某种识别方法可能比另一种方法更为适合。因特网上的主机和人类一样,可以使用多种识别方式进行标识。互联网上主机的一种标识方法是使用它的主机名,如 www.facebook.com、 www.google.com 等。但是这是我们人类的记忆方式,路由器不会这么理解,路由器喜欢定长的、有层次结构的 IP 地址,还记得什么是 IP 地址吗?
IP 地址现在简单表述一下,就是一个由 4 字节组成,并有着严格的层次结构。例如 121.7.106.83 这样一个 IP 地址,其中的每个字节都可以用 .
进行分割,表示了 0 - 255 的十进制数字。
然而,路由器喜欢的是 IP 地址进行解析,我们人类却便于记忆的是网址,那么路由器如何把 IP 地址解析为我们熟悉的网址地址呢?这时候就需要 DNS 出现了。
DNS 是一个由分层的 DNS 服务器 (DNS server)
实现的分布式数据库;它还是一个使得主机能够查询分布式数据库的应用层协议。DNS 服务器通常是运行 BIND (Berkeley Internet Name Domain) 软件的 UNIX 机器。DNS 协议运行在 UDP 上,使用 53 端口。
我们上面探讨的协议 HTTP、SMTP、DNS 都采用了客户-服务器模式,这种模式会极大依赖总是打开的基础设施服务器。而 P2P 是客户端与客户端模式,对总是打开的基础设施服务器有最小的依赖。
P2P 的全称是 Peer-to-peer, P2P,是一种分布式体系结构的计算机网络。在 P2P 体系中,所有的计算机和设备都被称为对等体,他们互相交换工作。对等网络中的每个对等方都等于其他对等方。网络中没有特权对等体,也没有主管理员设备。
从某种意义上说,对等网络是计算机世界中最平等的网络。每个对等方都相等,并且每个对等方具有与其他对等方相同的权利和义务。对等体同时是客户端和服务器。
实际上,对等网络中可用的每个资源都是在对等之间共享的,而无需任何中央服务器。P2P 网络中的共享资源可以是诸如处理器使用率,磁盘存储容量或网络带宽等。
P2P 的主要目标是共享资源并帮助计算机和设备协同工作,提供特定服务或执行特定任务。如前面说到的,P2P 用于共享各种计算资源,例如网络带宽或磁盘存储空间。 但是,对等网络最常见的例子是 Internet 上的文件共享。 对等网络非常适合文件共享,因为它们允许连接到它们计算机等同时接收文件和发送文件。BitTorrent 是 P2P 使用的主要协议。
P2P 网络具有一些使它们有用的特征:
- 很难完全掉线,即使其中的一个对等方掉线,其他对等方仍在运行并进行通信。 为了使 P2P(对等)网络停止工作,你必须关闭所有对等网络。对等网络具有很强的可扩展性。 添加新的对等节点很容易,因为你无需在中央服务器上进行任何中央配置。
- 当涉及到文件共享时,对等网络越大,速度越快。 在 P2P 网络中的许多对等点上存储相同的文件意味着当某人需要下载文件时,该文件会同时从多个位置下载。
TELNET 又称为远程登录,是一种应用层协议,它为用户提供了在本地机器上就能够操控远程主机工作的能力。例如下面这幅图所示。
主机 A 可以直接通过 TELNET 协议访问主机 B。
TELNET 利用 TCP 的一条连接,通过一条连接向主机发送文字命令并在主机上执行。
使用 TELNET 协议进行远程登录时需要满足一下几个条件:
- 必须知道远程主机的 IP 地址或者域名。
- 必须知道登录标识和口令。
TELNET 远程登录一般使用 23 端口。
TELNET 的工作过程如下:
- 本地主机与远程主机建立连接,这个连接其实是 TCP 连接,用户需要知道指定主机的 IP 地址或者域名
- 与远程主机建立连接后,在本地主机终端上输入的字符都会以
NVT (Net Virtual Terminal)
的形式发送至远程主机,这个过程实际上是发送一个数据包到远程主机。 - 远程主机接受数据包后,产生的输出会以 NVT 的格式发送给本地主机一个数据包,包括输入命令回显和命令执行结果
- 最后,本地主机终端对远程主机撤销链接,这个过程实际上就是 TCP 断开连接的过程。
TELNET 有一个非常明显的缺点,那就是在主机和远程主机的发送数据包的过程中是明文传输,未经任何安全加密,这样的后果是容易被互联网上不法分子嗅探到数据包来搞一些坏事,为了数据的安全性,我们一般使用 SSH 进行远程登录。
SSH 是加密的远程登录系统。使用 SSH 可以加密通信内容,即时数据包被嗅探和抓取也无法破解所包含的信息,除此之外,SSH 还有一些其他功能:
- SSH 可以使用更强的认证机制。
- SSH 可以转发文件。
- SSH 可以使用端口转发功能。
端口转发是 SSH 为网络安全通信使用的一种方法。SSH 可以利用端口转发技术来传输其他 TCP/IP 协议的报文,当使用这种方式时,SSH 就为其他服务在客户端和服务器端建立了一条安全的传输管道端口转发是指将特定端口号所收到的消息转发到指定 IP 地址和端口号的一种机制。
FTP (File Transfer Protocol,文件传输协议)
是应用层协议之一,它是计算机网络上用处最广的文件传输协议。
FTP 协议包括两个组成部分,分为 FTP 服务器和 FTP 客户端。其中 FTP 服务器用来存储文件,用户可以使用 FTP 客户端通过 FTP 协议访问位于 FTP 服务器上的资源。
由于 FTP 传输效率非常高,一般用来在网络上传输大的文件。
默认情况下 FTP 协议使用 TCP 端口中的 20 和 21 这两个端口,其中 20 用于传输数据,21 用于传输控制信息。FTP TCP 21 号端口上进行文件传输时,每次都会建立一个用于数据传输的 TCP 连接,数据传输完毕后,传输数据的这条连接也会被断开,在控制用的连接上继续进行命令或应答的处理。
TCP/IP 协议簇中还有一个简单文件传输协议(TFTP,Trivial File Transfer Protocol)
,它是一个很小且易于实现的文件传输协议。TFTP 也使用的是客户 - 服务器方式,只不过 TFTP 是基于 UDP 来传输报文的。由于 UDP 没有差错检测这一系列对报文完整性的要求,所以 TFTP 需要自己实现差错检测以及错误修改的动作,TFTP 的端口号默认为 69。
由于 TFTP 使用 UDP 来传输,所以当需要很多客户端下载文件时往往考虑这种方式;而且 TFTP 代码所占内存空间小,这对某些小型机或一些特殊设备比较重要,特殊设备比如某种小容量的只读存储器。当设备通电时,会执行只读存储器中的代码,然后在网络上广播一个 TFTP 请求,网络上的 TFTP 服务器会发送响应,响应中包括可执行的二进制程序,设备收到后会把程序放入内存中并开始执行。
TFTP 的主要特点是:
- 每次会传输 512 字节的数据,最后不足 512 字节的可作为结束标志位
- 报文按序号排序,从 1 开始
- 支持 ASCII 和二进制传输
- 可对文件进行读写
TFTP 工作时,每当发送完数据块时对等待对方确认,确认时应该指明所确认的块编号。如果规定时间内没有收到确认就会重发数据 PDU。
DHCP 协议的全称是 Dynamic Host Configuration Protocol,动态主机配置协议。简单来讲一句就是:这个协议能够让我们自动配置 IP 连接网络。
我们知道,在互联网中 IP 地址是标识网络上主机的一种方式,这个 IP 地址的配置方法有两种:一种是通过手动来设置 IP 地址,设置完成后不管你走到哪里这个 IP 地址不会改变,这会导致一个问题:你可能离开某个区域内就会导致无法连接网络;还有一种方式是自动配置 IP 地址,这样不管你走到哪里,你的网卡都会帮你连接上网。
DHCP 的前身是 BOOTP 协议,BOOTP 协议是一种引导协议,需要人工手动干预进行协议配置,非常不方便。于是 BOOTP 被淘汰了出现了 DHCP,根据上面的描述我们可以得出一个结论:DHCP 是一种即插即用式的协议。即插即用的意思就是插上就能用,不需要再手动设置 IP ,这一系列过程都由操作系统和网卡直接分配并设置好。如果你仔细观察过 IP 地址就会发现,当你在不同的地点时,你的 IP 地址会不断变化。
这一切的背后我会在后面详细聊 DHCP 的时候做全面的阐述。
提供电子邮件服务的协议叫做SMTP (Simple Mail Transfer Protocol)
,SMTP 在传输层也是用了 TCP 协议。
早期电子邮件是在发送端主机和接收端主机之间直接建立 TCP 连接。发送方编写好邮件之后会将邮件保存在磁盘中,然后与接受主机建立 TCP 连接,将邮件发送到接受主机的磁盘中。当发送方把邮件发送后,再从本地磁盘中删除邮件。如果接受主机因为特殊情况无法接收,发送端将等待一段时间后重新发送。
这种方法虽然能够保证电子邮件的完整性和有效性,但却不适合当今的互联网,因为早期的电子邮件只能在线发送,这种方式显然不够成熟。
针对于此,提出了邮件服务器的概念。邮件服务器构成了整个邮件系统的核心。每个接收方在其中的邮件服务器上会有一个邮箱 (mailbox)存在。用户的邮箱管理和维护发送给他的报文。
一个典型的邮件发送过程是:从发送方的用户代理开始,传输到发送方的邮件服务器,再传输到接收方的邮件服务器,然后在这里被分发到接收方的邮箱中。用接收方的用户想要从邮箱中读取邮件时,他的邮件服务器会对用户进行认证。如果发送方发送的邮件无法正确交付给接收方的服务器,那么发送方的用户代理会把邮件存储在一个报文队列中,并在以后尝试再次发送。通常每 30 分钟发送一次,如果一段时间后还发送不成功,服务器就会删除报文队列中的邮件并以电子邮件的方式通知发送方。
现在你知道了两台邮件服务器邮件发送的大体过程,那么,SMTP 是如何将邮件从 Alice 邮件服务器发送到 Bob 的邮件服务器的呢?主要分为下面三个阶段
- 建立连接:在这一阶段,SMTP 客户请求与服务器的25端口建立一个 TCP 连接。一旦连接建立,SMTP 服务器和客户就开始相互通告自己的域名,同时确认对方的域名。
- 邮件传送:一旦连接建立后,就开始邮件传输。SMTP 依靠 TCP 能够将邮件准确无误地传输到接收方的邮件服务器中。SMTP 客户将邮件的源地址、目的地址和邮件的具体内容传递给 SMTP 服务器,SMTP 服务器进行相应的响应并接收邮件。
- 连接释放:SMTP 客户发出退出命令,服务器在处理命令后进行响应,随后关闭 TCP 连接。
最一开始,互联网中的电子邮件只能处理文本格式,后来也逐渐扩展为 MIME 类型,我们上面也简单提到了一句 MIME 类型,MIME (Multipurpose Internet Mail Extensions)
是用途互联网邮件扩展类型。
它是一个互联网标准,扩展了电子邮件标准,使其能够支持很多格式,这些格式如下:
- 超文本标记语言文本 .html text/html
- xml文档 .xml text/xml
- 普通文本 .txt text/plain
- PNG图像 .png image/png
- GIF图形 .gif image/gif
- JPEG图形 .jpeg,.jpg image/jpeg
- AVI 文件 .avi video/x-msvideo 等。
文章涵盖了许多应用层协议,包括 HTTP、DNS、SMTP、FTP、TELNET 协议等
这些应用层协议我们在日常工作中都会用到,我们不仅仅是用户,还是程序员,势必要对其进行了解,我给你画了一些图帮助你理解清楚这些协议,简化的背后却是复杂而艰巨的规范标准和开发的复杂。
如果文章对你有帮助,希望各位小伙伴们三连走起!