[toc]

应用层

应用层协议原理

应用程序架构

应用层程序的体系结构一般包括:P2P、CS这两种架构。

  • P2P:P2P(Peer-to-Peer)是一种分布式计算和通信模型,它允许计算机之间直接连接和通信,而不需要通过中央服务器进行中转。在P2P网络中,所有的计算机节点都可以充当客户端和服务器的角色,可以共享资源、提供服务和请求服务。

    典型例子:p2p的下载等

  • CS:一直打开的一端被称为服务端(S),它会处理来自客户端请求;主动请求的一方就是客户端(C)。

    典型CS架构的应用:web服务

进程通信与套接字

进程通信

应用层解决的是两端应用程序(进程)通信的问题。两端进程是通过套接字通信,为用户进程提供套接字也是应用层的主要功能。网络通信的用户进程是运行在应用层上的。

套接字

套接字是同一台主机内应用层与运输层之间的接口,也是提供给应用程序的可编程接口,应用程序可以通过套接字控制和使用应用层的一切功能,但无法通过套接字控制运输层。

进程寻址

通过IP地址和端口号寻找接收方进程(具体来说是寻找接收方进程对应的套接字)。

动态主机配置协议:DHCP

DHCP 的全称是 Dynamic Host Configuration Protocol 动态主机配置协议。使用 DHCP 就能实现自动设置 IP 地址、统一管理 IP 地址分配。也就是不管你是在开会还是在工位干活,都省去了手动配置 IP 地址这一步繁琐的操作,同时 DHCP 也大大减少了可能由于你手动分配 IP 地址导致错误的几率。

DHCP 与 IP 密切相关,它是 IP 网络上所使用的协议。如果你想要使用 DHCP 提供服务的话,那么在整条通信链路上就需要 DHCP 服务器的存在,连接到网络的设备使用 DHCP 协议从 DHCP 服务器请求 IP 地址。DHCP 服务器会为设备分配一个唯一的 IP 地址。

img

除了 IP 地址外,DHCP 服务器还会把子网掩码,默认路由,DNS 服务器告诉你。

DHCP 服务器

现在,你不需要手动配置 IP 地址,也不再需要管理 IP 地址了,管理权已经移交给了 DHCP 服务器,DHCP 服务器会维护 IP 地址池,在网络上启动时会将地址租借给启用 DHCP 的客户端。

由于 IP 地址是动态的(临时分配)**而不是**静态的(永久分配),因此不再使用的 IP 地址会自动返回 IP 地址池中进行重新分配。

那么 DHCP 服务器由谁维护呢?

网络管理员负责建立 DHCP 服务器,并以租约的形式向启用 DHCP 的客户端提供地址配置,啊,既然不需要我管理,那就很舒服了~

好了,现在你能舒舒服服的开发了,你用 postman 配了一条 192.168.1.4/x/x 的接口进行请求,请求能够顺利进行,但是过了一段时间后,你发现 192.168.1.4/x/x 这个接口请求不通了,这是为啥呢?然后你用 ipconfig 查询了一下自己的 IP 地址,发现 IP 地址变成了 192.168.1.7,怎么我用着用着 IP 地址还改了?DHCP 是个垃圾,破玩意!!@#¥%¥%……¥%

其实,这也是一个 DHCP 服务器的一个功能,DHCP 服务器通常为每个客户端分配一个唯一的动态 IP 地址,当该 IP 地址的客户端租约到期时,该地址就会更改。

唯一意思说的就是,如果你手动设置了一个静态 IP,同时 DHCP 服务器分配了一个动态 IP,这个动态 IP 和静态 IP 一样,那么必然会有一个客户端无法上网。

我就遇到过这种情况,我使用虚拟机配置的静态 IP 是192.168.1.8,手机使用 DHCP 也同样配置了 192.168.1.8 的 IP 地址,此时我的虚拟机还没有接入网络,当我接入网络时,我怎样也连不上虚拟机了,一查才发现 IP 地址冲突了 …

虽然 DHCP 服务器能提供 IP 地址,但是他怎么知道哪些 IP 地址空闲,哪些 IP 地址正在使用呢?

实际上,这些信息都配置在了数据库中,下面我们就来一起看一下 DHCP 服务器维护了哪些信息。

  • 网络上所有有效的 TCP/IP 配置参数

这些参数主要包括主机名(Host name)、DHCP 客户端(DHCP client)、域名(Domain name)、IP 地址IP address)、网关(Netmask)、广播地址(Broadcast address)、默认路由(default rooter)

  • 有效的 IP 地址和排除的 IP 地址,保存在 IP 地址池中等待分配给客户端
  • 为某些特定的 DHCP 客户端保留的地址,这些地址是静态 IP,这样可以将单个 IP 地址一致地分配给单个DHCP 客户端

好了,现在你知道 DHCP 服务器都需要保存哪些信息了,并且看过上面的内容,你应该知道一个 DHCP 的组件有哪些了,下面我们就来聊一聊 DHCP 中都有哪些组件,这些组件缺一不可。

DHCP 的组件

使用 DHCP 时,了解所有的组件很重要,下面我为你列出了一些 DHCP 的组件和它们的作用都是什么。

  • DHCP Server,DHCP 服务器,这个大家肯定都知道,因为我们上面就一直在探讨 DHCP 服务器的内容,使用 DHCP ,是一定要有 DHCP 服务器的,要不然谁给你提供服务呢?
  • DHCP Client,DHCP 客户端,这个大家应该也知道,毕竟只有一个服务端不行啊,没有客户端你为谁服务啊?DHCP 的客户端可以是计算机、移动设备或者其他需要连接到网络的任何设备,默认情况下,大多数配置为接收 DHCP 信息
  • Ip address pool: 你得有 IP 地址池啊,虽然说你 DHCP 提供服务,但是你也得有工具啊,没有工具玩儿啥?IP 地址池是 DHCP 客户端可用的地址范围,这个地址范围通常由最低 -> 最高顺序发送。
  • Subnet:这个组件是子网,IP 网络可以划分一段一段的子网,子网更有助于网络管理。
  • Lease:租期,这个表示的就是 IP 地址续约的期限,同时也代表了客户端保留 IP 地址信息的时间长度,一般租约到期时,客户端必须续约。
  • DHCP relay:DHCP 中继器,这个一般比较难想到,DHCP 中继器一般是路由器或者主机。DHCP 中继器通常应对 DHCP 服务器和 DHCP 客户端不再同一个网断的情况,如果 DHCP 服务器和 DHCP 客户端在同一个网段下,那么客户端可以正确的获得动态分配的 IP 地址;如果不在的话,就需要使用 DHCP 中继器进行中继代理。

现在 DHCP 的组件你了解后,下面我就要和你聊聊 DHCP 的工作机制了。

DHCP 工作机制

在聊 DHCP 工作机制前,先来看一下 DHCP 的报文消息

DHCP 报文

DHCP 报文共有一下几种:

  • DHCP DISCOVER :客户端开始 DHCP 过程发送的包,是 DHCP 协议的开始
  • DHCP OFFER :服务器接收到 DHCPDISCOVER 之后做出的响应,它包括了给予客户端的 IP 租约过期时间、服务器的识别符以及其他信息
  • DHCP REQUEST :客户端对于服务器发出的 DHCPOFFER 所做出的响应。在续约租期的时候同样会使用。
  • DHCP ACK :服务器在接收到客户端发来的 DHCPREQUEST 之后发出的成功确认的报文。在建立连接的时候,客户端在接收到这个报文之后才会确认分配给它的 IP 和其他信息可以被允许使用。
  • DHCP NAK :DHCPACK 的相反的报文,表示服务器拒绝了客户端的请求。
  • DHCP RELEASE :一般出现在客户端关机、下线等状况。这个报文将会使 DHCP 服务器释放发出此报文的客户端的 IP 地址
  • DHCP INFORM :客户端发出的向服务器请求一些信息的报文
  • DHCP DECLINE :当客户端发现服务器分配的 IP 地址无法使用(如 IP 地址冲突时),将发出此报文,通知服务器禁止使用该 IP 地址。

DHCP 的工作机制比较简单,无非就是客户端向服务器租借 IP ,服务器提供 IP 给客户端的这个过程呗。嗯,你很聪明,大致是这样的,不过有一些细节需要注意下,下面我通过两张图来和你聊一下。

关于从 DHCP 中获取 IP 地址的流程,主要分为两个阶段。

第一个阶段是 DHCP 查找包的阶段

img

查找包的阶段主要分为两步:第一步是 DHCP 发现包,第二步是 DHCP 提供包。

DHCP 客户端在通信链路上发起广播,看看链路上有没有能提供 DHCP 包的服务器,然后通信链路上的各个节点会检查自己是否能够提供 DHCP 包,这时 DHCP 服务器说它能够提供 DHCP 包,然后 DHCP 就发出一个 DHCP 包沿着通信链路返回给 DHCP 客户端。

第二个阶段是 DHCP 的请求阶段。

img

DHCP 的请求包也分为两步:第一步是 DHCP 请求包,第二步是 DHCP 确认包。

DHCP 客户端在通信链路上发起 DHCP 请求包,请求包主要是告诉 DHCP 服务器,它想要用上一步提供的网络设置,然后 DHCP 服务器向 DHCP 客户端发送确认包,表示允许 DHCP 客户端使用第二步发送的网络设置。

至此,DHCP 的网络设置就结束了,然后通信链路上的主机之间就可以进行 TCP/IP 通信了。

当不需要 IP 地址时,可以发送 DHCP 解除包(DHCP RELEASE)进行解除。另外,DHCP 的设置中通常会有一个租期时间的设定,DHCP 客户端在这个时限内可以发送 DHCP 请求包通知想要延长这个期限。

超文本传输协议:HTTP

HTTP概况

http概况

  • HTTP是一个在计算机的世界里专门在两点之间传输超文本数据的约定和规范。

非持续连接与持续连接

RTT

RTT(Round-Trip Time) 往返时间指的是一个段分组从客户到服务器然后再返回客户所花费的时间。我们尝试用RTT来表示客户点击超链接后页面出现的时间,如下图所示:

img

粗略地讲,总的响应时间就是两个RTT 再加上服务器传输HTML文件的时间

非持续连接

每个请求/响应都是一个单独的TCP连接,每次请求完毕,都会释放连接。

非持续连接的缺点:

  • 必须为每个请求的对象都创建对象,建立和维护一个全新的连接。这对web服务端来说,会引起内存开销大,耗损性能的问题
  • 每个请求的对象经受两倍的RTT交付时延,累积起来后,成本依旧不菲.

持续连接

每个请求/响应都是经过相同的TCP连接发送的,复用了这个TCP连接。

HTTP性能

HTTP事务延时

一个HTTP事务是指,一个HTTP请求从发出到响应到达发送端的过程,如下所示:

img

上图显示一个HTTP事务的时延主要包括4部分:

1、DNS查询:如果从本地DNS缓存就能得到目标IP地址,则耗时0RTT;如果从本地DNS服务器就能得到目标IP地址,则耗时1个RTT;如果涉及到DNS的递归和迭代请求,则耗时多个RTT。

2、TCP连接的三次握手,占 1 个RTT,如果使用TLS安全连接则占3个RTT。

3、请求到达服务器和响应返回的时间,占1个RTT。

4、服务器应用程序处理请求的时间,假设请求的是一个静态文件,则处理时间可以忽略不记。

TCP相关的时延

HTTP协议是基于TCP协议的,因此一个HTTP事务的性能很大程度取决于TCP通道的性能,下面是一些TCP连接相关的可能会拖慢HTTP的地方:

1、TCP连接的3次握手时延

花费 1个 RTT。越小的HTTP事务在TCP连接下的效率越低。

2、捎带机制

接收方在接收到一个序号的分组后不会马上返回ACK报文,而是允许接收方在有数据发往发送方的分组中“捎带”这个ACK消息(ACK标志位和ACK号),这是考虑到ACK确认报文很小,单独发一个报文会比较浪费(TCP头部就占了40~60字节)。

这也会给HTTP响应带来时延。

3、TCP慢启动

TCP慢启动使 刚打开的连接 传输分组的速度很慢。

4、Nagle算法 和 TCP_NODELAY

Nagle算法是为了防止一次分组发送的实际数据量太少,造成网络效率降低,所以要求缓冲区需要到达MSS及以上大小的数据时才发送分组(或者发送计时器到时)。如果缓冲区里的数据不足一个MSS大小,那么要等到在前一个分组被确认之后或者发送计时器超时才能发下一个分组。

Naggle会引发几种HTTP性能问题:小的HTTP报文无法填满一个MSS,所以只能等到计时器到达才能发送;延迟确认会阻止Naggle发送下一个分组(延迟确认和Naggle共同作用)。

HTTP应用程序会设置参数TCP_NODELAY禁用Naggle算法。当然,TCP应用Nagle算法时,要保证应用程序每次向缓冲区输送的数据块得是较大的数据块(如512B)而不能时逐字节发送。

5、TIME_WAIT 累积和端口耗尽

主动关闭连接的一方(不论是服务器还是客户端)进入TIME_WAIT后,主动关闭方会在内存中记录最近所关闭的对端IP地址和端口,记录有效期维持2MSL,2MSL内连接并不会真正关闭。在这段期间内,该端不会与对端建立相同IP和端口的连接。

假如A和B以很快的速率创建和关闭连接(也就是在2MSL时间内,端口还是被占用了),B就没有端口可以和A的80服务建立连接了,这就是端口耗尽(是客户端B的端口耗尽),当然这种情况很少出现,只会出现在性能测试的时候。

对于服务端,服务端如果有大量的TIME_WAIT未关闭连接也会使操作系统的速度严重减慢(如果使用多线程则一个连接可能就是一个线程)和消耗大量内存(毕竟一个连接是一个套接字)。

TCP连接过多意味着什么?

1、大量的套接字会占用客户端、服务器以及代理的内存(输入输出缓冲区要预先分配的)和CPU;

2、并行 TCP 连接接收和发送数据时竞争共享的带宽;

3、应用的并行能力也受限制(管理一个套接字可能就要用一个线程)。

HTTP优化建议

从大方向上,HTTP优化只会围绕2点进行:减少 网络延迟 和 减少要传输的字节。具体可以通过以下几点进行优化:

1、减少DNS查询次数

尽量命中本地DNS缓存和加长DNS缓存记录的过期时间。

2、减少HTTP请求

任何请求都不如没有请求更快,因此要去掉页面上没有必要的资源,多次请求尽可能合并为1次请求。

3、使用CDN

从地理上把数据放到接近客户端的地方,可以显著减少每次请求的传播时延。

4、添加Expires首部并配置ETag标签

相关资源应该缓存,以避免重复请求每个页面中相同的资源。Expires 首部可用 于指定缓存时间,在这个时间内可以直接从缓存取得资源,完全避免 HTTP 请求。ETag 及 Last-Modified 首部提供了一个与缓存相关的机制,相当于最后一次 更新的指纹或时间戳。

5、Gzip资源

所有文本资源都应该使用 Gzip 压缩,再传输。

6、避免HTTP重定向

HTTP 重定向极其耗时,特别是把客户端定向到一个完全不同的域名的情况下, 还会导致额外的 DNS 查询、TCP 连接延迟,等等。

web缓存

web缓存器也叫代理服务器,主要用于缓存本地对于远端服务器响应的内容,减少对远端服务器的请求。

HTTP协议演进

HTTP1.0

特点

  • 无状态:服务器不跟踪不记录请求过的状态
  • 无连接:浏览器每次请求都需要建立TCP连接

HTTP/1.0规定浏览器和服务器保持短连接。浏览器的每次请求都需要与服务器建立一个TCP连接,服务器处理完成后立即断开TCP连接(无连接),服务器不跟踪每个客户端也不记录过去的请求(无状态

无状态导致的问题可以借助cookie/session机制来做身份认证和状态记录解决。

然而,无连接特性将会导致以下性能缺陷

  • 无法复用连接

    每次发送请求的时候,都需要进行一次TCP连接,而TCP的连接释放过程又是比较费事的。这种无连接的特性会导致网络的利用率非常低。

  • 队头堵塞(head of line blocking)

    由于HTTP/1.0规定下一个请求必须在前一个请求响应到达之前才能发送。假设一个请求响应一直不到达,那么下一个请求就不发送,就到导致阻塞后面的请求。

为了解决这些问题,HTTP/1.1出现了。

HTTP1.1

  • 长连接

    HTTP/1.1增加了一个Connection字段,通过设置Keep-alive(默认已设置)可以保持连接不断开,避免了每次客户端与服务器请求都要重复建立释放TCP连接,提高了网络的利用率。如果客户端想关闭HTTP连接,可以在请求头中携带Connection:false来告知服务器关闭请求

  • 支持断点续传

    通过使用请求头中的 Range 来实现。

  • 支持请求管道化(pipelining)

    基于HTTP/1.1的长连接,使得请求管线化成为可能。多个请求可以同时发送,但是服务器还是按照顺序,先回应 A 请求,完成后再回应 B 请求。要是 前面的回应特别慢,后面就会有许多请求排队等着。这称为「队头堵塞」。

HTTP2

http2.0是一种安全高效的下一代http传输协议。安全是因为http2.0建立在https协议的基础上,高效是因为它是通过二进制分帧来进行数据传输。正因为这些特性,http2.0协议也在被越来越多的网站支持。

特点
  • 对1.x协议语意的完全兼容

    2.0协议是在1.x基础上的升级而不是重写,1.x协议的方法,状态及api在2.0协议里是一样的。

  • 建立在HTTPS上

  • 性能的大幅提升

    2.0协议重点是对终端用户的感知延迟、网络及服务器资源的使用等性能的优化。

二进制分帧

http2.0之所以能够突破http1.X标准的性能限制,改进传输性能,实现低延迟和高吞吐量,就是因为其新增了二进制分帧层。

帧(frame)包含部分:类型Type, 长度Length, 标记Flags, 流标识Stream和frame payload有效载荷。

消息(message):一个完整的请求或者响应,比如请求、响应等,由一个或多个 Frame 组成。

流是连接中的一个虚拟信道,可以承载双向消息传输。每个流有唯一整数标识符。为了防止两端流ID冲突,客户端发起的流具有奇数ID,服务器端发起的流具有偶数ID。

流标识是描述二进制frame的格式,使得每个frame能够基于http2发送,与流标识联系的是一个流,每个流是一个逻辑联系,一个独立的双向的frame存在于客户端和服务器端之间的http2连接中。一个http2连接上可包含多个并发打开的流,这个并发流的数量能够由客户端设置。

在二进制分帧层上,http2.0会将所有传输信息分割为更小的消息和帧,并对它们采用二进制格式的编码将其封装,新增的二进制分帧层同时也能够保证http的各种动词,方法,首部都不受影响,兼容上一代http标准。其中,http1.X中的首部信息header封装到Headers帧中,而request body将被封装到Data帧中。

图片

多路复用/连接共享

而http2.0中的多路复用优化了这一性能。多路复用允许同时通过单一的http/2 连接发起多重的请求-响应消息。有了新的分帧机制后,http/2 不再依赖多个TCP连接去实现多流并行了。每个数据流都拆分成很多互不依赖的帧,而这些帧可以交错(乱序发送),还可以分优先级,最后再在另一端把它们重新组合起来。

http 2.0 连接都是持久化的,而且客户端与服务器之间也只需要一个连接(每个域名一个连接)即可。http2连接可以承载数十或数百个流的复用,多路复用意味着来自很多流的数据包能够混合在一起通过同样连接传输。当到达终点时,再根据不同帧首部的流标识符重新连接将不同的数据流进行组装。

图片

上图展示了一个连接上的多个传输数据流:客户端向服务端传输数据帧stream5,同时服务端向客户端乱序发送stream1和stream3。这次连接上有三个响应请求乱序并行交换。

图片

上图就是http1.X和http2.0在传输数据时的区别。以货物运输为例再现http1.1与http2.0的场景:

http1.1过程:货轮1从A地到B地去取货物,取到货物后,从B地返回,然后货轮2在A返回并卸下货物后才开始再从A地出发取货返回,如此有序往返。

http2.0过程:货轮1、2、3、4、5从A地无序全部出发,取货后返回,然后根据货轮号牌卸载对应货物。

显然,第二种方式运输货物多,河道的利用率高。

头部压缩

缓存与压缩头部

http1.x的头带有大量信息,而且每次都要重复发送。http/2使用encoder来减少需要传输的header大小,通讯双方各自缓存一份头部字段表,既避免了重复header的传输,又减小了需要传输的大小。

当然,HTTP1.x的GIZP压缩是对body的压缩,与http2的头部压缩不冲突。

请求优先级

http2采用二进制分帧,所以可以允许帧乱序传输,会在客户端重新组装成正确的序列。因此,我们可以在建立好的HTTP2连接里,可以为优先级高的请求优先发送数据帧。

例如:

●优先级最高:主要的html

●优先级高:CSS文件

●优先级中:js文件

●优先级低:图片

服务器端推送

服务器可以对一个客户端请求发送多个响应,服务器向客户端推送资源无需客户端明确地请求。并且,服务端推送能把客户端所需要的资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤。

HTTP2的性能瓶颈

启用http2.0后会给性能带来很大的提升,但同时也会带来新的性能瓶颈。因为现在所有的压力集中在底层一个TCP连接之上,TCP很可能就是下一个性能瓶颈,比如TCP分组的队首阻塞问题,单个TCP packet丢失导致整个连接阻塞,无法逃避,此时所有消息都会受到影响。

HTTP/1.x keep-alive 与 HTTP/2 多路复用区别

  • HTTP/1.x 是基于文本的,只能整体去传;HTTP/2 是基于二进制流的,可以分解为独立的帧,交错发送
  • HTTP/1.x keep-alive 必须按照请求发送的顺序返回响应;HTTP/2 多路复用不按序响应
  • HTTP/1.x keep-alive 为了解决队头阻塞,将同一个页面的资源分散到不同域名下,开启了多个 TCP 连接;HTTP/2 同域名下所有通信都在单个连接上完成
  • HTTP/1.x keep-alive 单个 TCP 连接在同一时刻只能处理一个请求(两个请求的生命周期不能重叠);HTTP/2 单个 TCP 同一时刻可以发送多个请求和响应

HTTP3

基于Google的QUIC,HTTP3 背后的主要思想是放弃 TCP,转而使用基于 UDP 的 QUIC 协议。

与 HTTP2 在技术上允许未加密的通信不同,QUIC 严格要求加密后才能建立连接。此外,加密不仅适用于 HTTP 负载,还适用于流经连接的所有数据,从而避免了一大堆安全问题。建立持久连接、协商加密协议,甚至发送第一批数据都被合并到 QUIC 中的单个请求/响应周期中,从而大大减少了连接等待时间。如果客户端具有本地缓存的密码参数,则可以通过简化的握手(0-RTT)重新建立与已知主机的连接。

为了解决传输级别的线头阻塞问题,通过 QUIC 连接传输的数据被分为一些流。流是持久性 QUIC 连接中短暂、独立的“子连接”。每个流都处理自己的错误纠正和传递保证,但使用连接全局压缩和加密属性。每个客户端发起的 HTTP 请求都在单独的流上运行,因此丢失数据包不会影响其他流/请求的数据传输。

特点

  • 基于google的QUIC协议,而quic协议是使用udp实现的;
  • 减少了tcp三次握手时间,以及tls握手时间;
  • 解决了http 2.0中前一个stream丢包导致后一个stream被阻塞的问题;
  • 优化了重传策略,重传包和原包的编号不同,降低后续重传计算的消耗;
  • 连接迁移,不再用tcp四元组确定一个连接,而是用一个64位随机数来确定这个连接;
  • 更合适的流量控制。

简单邮件传输协议:SMTP

下图给出了电子邮件系统的总体情况,我们可以看到它有3个主要的组成部分:用户代理、邮件服务器、SMTP

img

用户代理,比如说:Foxmail,Outlook,Apple Mail 这类的软件

邮件服务器:qq邮箱,163邮箱,Gmail之类的邮件服务

SMTP则是简单邮件传输协议

SMTP是因特网电子邮件的核心。它使用TCP可靠数据传输服务。每台邮件服务器上既运行着SMTP的客户端也运行着SMTP的服务器端。当一个邮件服务器向其他邮件服务器发送邮件时,他就是SMTP的客户;当邮件服务器从其他邮件服务器上接收邮件时,他就表现为一个SMTP的服务器

假设Alice 想给 Bob发送一份简单的报文。

  1. Alice调用它的邮件代理程序并提供Bob的邮件地址,撰写报文,然后指示用户代理发送该报文
  2. Alice的用户代理把报文发给她的邮件服务器,在那里,该报文被放在报文队列中
  3. 运行在Alice的邮件服务器上的SMTP客户端发现了报文队列中的这个报文,他就创建一个到运行在Bob的邮件服务器上的SMTP服务器的TCP连接
  4. 在经过一些初始的SMTP握手后,SMTP客户通过该TCP连接发送Alice的报文。
  5. 在Bob的邮件服务器上,SMTP的服务器端接收该报文。Bob的邮件服务器然后将该报文放入Bob的邮箱中。
  6. 在Bob有时间的时候,它调用用户代理阅读该报文。

img

注意:SMTP 一般不适用中间邮件服务器发送邮件,如果Bob的邮件服务器没有开机,该报文会保留在ALice的邮件服务器上并等待新的尝试。

现在你知道了两台邮件服务器邮件发送的大体过程,那么,SMTP 是如何将邮件从 Alice 邮件服务器发送到 Bob 的邮件服务器的呢?

主要分为下面三个阶段:

  • 建立连接:在这一阶段,SMTP 客户请求与服务器的25端口建立一个 TCP 连接。一旦连接建立,SMTP 服务器和客户就开始相互通告自己的域名,同时确认对方的域名。
  • 邮件传送:一旦连接建立后,就开始邮件传输。SMTP 依靠 TCP 能够将邮件准确无误地传输到接收方的邮件服务器中。SMTP 客户将邮件的源地址、目的地址和邮件的具体内容传递给 SMTP 服务器,SMTP 服务器进行相应的响应并接收邮件。
  • 连接释放:SMTP 客户发出退出命令,服务器在处理命令后进行响应,随后关闭 TCP 连接。

HTTP vs SMTP

相同点

  • HTTP 是从Web服务器向Web客户传送文件;SMTP事一个邮件服务器向另一个邮件服务器传送文件
  • 当进行文件传送时,持续的HTTP和SMTP都采用持续连接

不同点

  • HTTP主要是 拉协议(pull protocol),即用户使用HTTP从该服务器拉取信息;而SMTP基本上是一个推协议(push protocol),及发送邮件服务器把文件推向接收邮件服务器
  • SMTP要求每个报文采用 7 比特的ASCII 码格式。HTTP数据则不受这些限制
  • HTTP把每个对象分装到它自己的HTTP响应报文中去,而SMTP则把所有报文对象放在一个报文之中

因特网邮件访问协议

Bob的用户代理不能使用SMTP得到报文,因为获取报文是一个拉操作,而SMTP协议是一个推协议。这就需要引入一个特殊的邮件访问协议来解决,该协议将Bob邮件服务器上的报文传送给他本地的PC。目前有一些流行的访问协议:POP3、IMAP以及HTTP

POP3

POP3 是一个极为简单的邮件访问协议。POP3按照三个阶段进行工作:

  1. Authorization(特许),用户代理发送用户名和口令以鉴别用户
  2. 事务处理阶段,用户代理取回报文。同时还能进行如下操作:对报文做删除标记,取消报文删除标记,获取邮件统计信息
  3. 更新阶段,出现在客户发出了quit命令之后,目的是结束该POP3会话。这时,该邮件服务器会删除那些被标记为删除的报文

在POP3的事务处理过程中,用户代理的回答可能有OK(正常)和-ERR(出现差错)

在事务处理阶段,POP3的用户代理通常被配置为”下载并删除”或者“下载并保留”方式。

下载并删除

这种方式存在的问题是,邮件接收方Bob可能是移动的,可能希望从多个不同的机器访问他的邮件报文,如从办公室的PC和笔记本来访问邮件。那么,如果Bob先在办公室的PC上收取了一条邮件,那么晚上当他在家里时,他便不能再通过笔记本收取该邮件

下载并保留

用户代理下载某邮件之后该邮件仍然保留在邮件服务器上。这样Bob就能通过不同的及其重新读取这些邮件

IMAP

IMAP 是另一个邮件访问协议,它比 POP3具有更多的特色,不过也比POP3复杂得多。 POP3 会对移动用户带来问题。IMAP更喜欢使用一个在远程服务器上的层次文件夹,这样他可以从任何一台机器上对所有报文进行访问,但是POP3协议并没有给用户提供任何创建远程文件夹并为报文指派文件夹的方法。

  • IMAP服务器把每个报文与一个文件夹联系起来,当报文第一次到达服务器时,它与收件人的INBOX文件夹相关联。收件人作为能够把邮件移到一个新的用户创建的文件夹中来阅读邮件、删除邮件等。
  • IMAP协议为用户提供了创建文件夹以及将邮件从一个文件夹移动到另一个文件夹的命令
  • IMAP 还为用户提供了在远程文件夹中查询邮件的命令
  • IMAP 服务器维护了IMAP会话的用户状态信息
  • IMAP 具有允许用户代理获取报文某些部分的命令。例如,一个用户代理可以只读取一个报文的首部。

基于Web的电子邮件

比如网页端的QQ邮箱,网易邮箱。使用这种服务,用户代理就是普通的浏览器,用户和他远程邮箱之间的通信通过HTTP进行:

  • 收件人从邮箱中访问一个报文时,该电子邮件报文从Bob的邮件服务器发送到他的浏览器,使用的是HTTP而不是POP3或者IMAP协议
  • 当发件人要发送一封电子邮件报文时,该电子邮件豹纹从浏览器发送到邮件服务器使用的是HTTP报文而不是SMTP
  • 但是,邮件服务器之间发送和接收邮件时,仍然使用SMTP

文件传输协议:FTP

FTP 概述

  • 文件传送协议 FTP (File Transfer Protocol) 是因特网上使用得最广泛的文件传送协议。
  • FTP 提供交互式的访问,允许客户指明文件的类型与格式,并允许文件具有存取权限。
  • FTP 屏蔽了各计算机系统的细节,因而适合于在异构网络中任意计算机之间传送文件。

FTP 的基本工作原理

  • FTP 使用 TCP 进行连接,它需要两个连接来传送一个文件:
    • 控制连接:服务器打开端口号 21 等待客户端的连接,客户端主动建立连接后,使用这个连接将客户端的命令传送给服务器,并传回服务器的应答。
    • 数据连接:用来传送一个文件数据。
  • 根据数据连接是否是服务器端主动建立,FTP 有主动和被动两种模式:
    • 主动模式:服务器端主动建立数据连接,其中服务器端的端口号为 20,客户端的端口号随机,但是必须大于 1024,因为 0~1023 是熟知端口号。
    • 被动模式:客户端主动建立数据连接,其中客户端的端口号由客户端自己指定,服务器端的端口号随机。
    • 主动模式要求客户端开放端口号给服务器端,需要去配置客户端的防火墙。被动模式只需要服务器端开放端口号即可,无需客户端配置防火墙。但是被动模式会导致服务器端的安全性减弱,因为开放了过多的端口号。
    • 当NAT(Network Address Translation)设备以主动模式访问FTP服务器时,由于NAT设备不会聪明的变更FTP包中的IP地址,从而导致无法访问服务器。

简单文件传送协议 TFTP

  • TFTP 是一个很小且易于实现的文件传送协议。

  • TFTP 使用客户服务器方式和使用 UDP 数据报,因此 TFTP 需要有自己的差错改正措施。

  • TFTP 只支持文件传输而不支持交互。

  • TFTP 没有一个庞大的命令集,没有列目录的功能,也不能对用户进行身份鉴别。

  • TFTP 的主要特点是

    (1) 每次传送的数据 PDU 中有 512 字节的数据,但最后一次可不足 512 字节。

    (2) 数据 PDU 也称为文件块(block),每个块按序编号,从 1 开始。

    (3) 支持 ASCII 码或二进制传送。

    (4) 可对文件进行读或写。

    (5) 使用很简单的首部。

远程终端协议 TELNET

简述

  • TELNET 是一个简单的远程终端协议,也是因特网的正式标准。
  • 用户用 TELNET 就可在其所在地通过 TCP 连接注册(即登录)到远地的另一个主机上(使用主机名或 IP 地址)。
  • TELNET 能将用户的击键传到远地主机,同时也能将远地主机的输出通过 TCP 连接返回到用户屏幕。这种服务是透明的,因为用户感觉到好像键盘和显示器是直接连在远地主机上。

域名系统:DNS

首先我们要搞清楚 主机名和IP地址的关系。

主机名如:facebook.com、google.com 等 但是,主机名几乎没有提供关于主机在因特网中位置的信息,这让路由器难以处理

IP 地址: 由4个字节组成,并有着严格的层次结构。例如 121.7.106.83 这样一个 IP 地址,其中的每个字节都可以用 . 进行分割,表示了 0 - 255 的十进制数字。

我们需要一种进行主机名到IP地址转换的目录服务,这就是DNS的主要任务。DNS是:

  1. 一个由分层的DNS服务器实现的分布式数据库
  2. 一个使得主机能够查询分布式数据库的应用层协议

如下图所示:

img

总的来说,在单一DNS服务器上运行集中式数据库完全没有可扩展能力。因此,DNS采用了分布式设计方案。

DNS 是一个复杂的系统,我们在这里只是就其运行的主要方面进行学习,下面给出一个 DNS 工作过程的总体概述

假设运行在用户主机上的某些应用程序(如 Web 浏览器或邮件阅读器) 需要将主机名转换为 IP 地址。这些应用程序将调用 DNS 的客户端,并指明需要被转换的主机名。用户主机上的 DNS 收到后,会使用 UDP 通过 53 端口向网络上发送一个 DNS 查询报文,经过一段时间后,用户主机上的 DNS 会收到一个主机名对应的 DNS 回答报文。因此,从用户主机的角度来看,DNS 就像是一个黑盒子,其内部的操作你无法看到。但是实际上,实现 DNS 这个服务的黑盒子非常复杂,它由分布于全球的大量 DNS 服务器以及定义了 DNS 服务器与查询主机通信方式的应用层协议组成。

DNS 最早的一种简单设计只是在因特网上使用一个 DNS 服务器。该服务器会包含所有的映射。这是一种集中式的设计,这种设计并不适用于当今的互联网,因为互联网有着数量巨大并且持续增长的主机,这种集中式的设计会存在以下几个问题

  • 单点故障(a single point of failure),如果 DNS 服务器崩溃,那么整个网络随之瘫痪。
  • 通信容量(traaffic volume),单个 DNS 服务器不得不处理所有的 DNS 查询,这种查询级别可能是上百万上千万级
  • 远距离集中式数据库(distant centralized database),单个 DNS 服务器不可能 邻近 所有的用户,假设在美国的 DNS 服务器不可能临近让澳大利亚的查询使用,其中查询请求势必会经过低速和拥堵的链路,造成严重的时延。
  • 维护(maintenance),维护成本巨大,而且还需要频繁更新。

所以 DNS 不可能集中式设计,它完全没有可扩展能力,因此采用分布式设计,所以这种设计的特点如下

分布式、层次数据库

没有一台DNS服务器拥有因特网上所有主机的映射。大致来说,有3种类型的DNS服务器:根DNS服务器、顶级域DNS服务器和权威DNS服务器。

img
根DNS服务器

有400多个根服务器遍及全世界。根名字服务器提供TLD服务器的IP地址

顶级域DNS服务器。

对于每个顶级域(如com、org、edu) 和所有国家的顶级域(uk,cn)等,都有TLD(Top-Level Domain)服务器. TLD服务器提供了权威DNS服务器的IP地址

权威DNS服务器

一个组织机构的权威DNS收藏了DNS记录。另一种方法是,该组织能够支付费用,让这些记录存储在某个服务提供商的一个权威DNS服务器中。多数大学和大公司实现和维护他们自己基本和备份的权威DNS服务器。

查询方式

第一个步骤是本机向本地域名服务器发出一个DNS请求报文,报文里携带需要查询的域名;第二个步骤是本地域名服务器向本机回应一个DNS响应报文,里面包含域名对应的IP地址或者别名等。由两种查询方法:

**递归查询:**本机向本地域名服务器发出一次查询请求,就静待最终的结果。如果本地域名服务器无法解析,自己会以DNS客户机的身份向其它域名服务器查询,直到得到最终的IP地址告诉本机

**迭代查询:**本地域名服务器向根域名服务器查询,根域名服务器告诉它下一步到哪里去查询,然后它再去查,每次它都是以客户机的身份去各个服务器查询

注意:理论上,任何DNS查询机可以是迭代的也可以是递归的。 在实践中,第一个步骤从主机到本地域名服务器是递归查询;第二大步骤中采用的是迭代查询,其实是包含了很多小步骤的,如下图所示。

img