网络应用

协议特点

每个应用层协议都是为了解决某一类应用问题,而问题的解决又往往是通过位于不同主机中的多个应用进程之间的通信和协同工作来完成的。应用层的具体内容就是规定应用进程在通信时所遵循的协议。 应用层的许多协议都是基于客户服务器方式。

客户(client)和服务器(server)都是指通信中所涉及的两个应用进程。客户服务器方式所描述的是进程之间服务和被服务的关系。客户是服务请求方,服务器是服务提供方。

研发

网络应用是计算机网络存在的理由,它存在于不同的端系统上,而不是网络核心设备上,这种设计促进了应用程序的研发;

常见的应用有电子邮件,Web,即时讯息,远程登陆,P2P文件共享,多用户网络游戏,流式存储视频片段,因特网电话,实时视频会议;

体系结构

应用体系结构(application architecture)由应用程序研发者设计,常见的包括

  • 客户端-服务器体系架构(client-server architecture):总是存在一个打开的服务器主机,接受来自客户主机的请求,具有固定的、众所周知的地址,主机群集常被用于创建强大的虚拟服务器;客户之间不能相互通信,同服务端通信,间断和服务器进行连接,拥有动态的地址;
  • P2P体系结构(P2P architecture):对数据中心专用服务器几乎没有依赖,应用程序在对等主机间通信;通常不需要庞大的服务器群和带宽;对等放间歇连接并改变地址,具有自拓展性和高度非集中式结构;但可能难以管理;

有时也会有将两种体系结构混合使用的应用,比如Napster,即时讯息;

进程通信

从操作系统的角度来看,通信的实体是进程;同一主机上的两个进程通过内部进程通信机制进行通信;不同主机上的进程通过跨越计算机网络交换报文而相互通信;

  • 成对的进程中,发起通信方表示为客户,会话开始时等待联系方标识为服务器;
  • 进程通过套接字接口向网络发送和接受报文;
  • 进程寻址需要定义1. 主机地址 2. 目的主机指定接受进程的标识符;

套接字

套接字(socket)是应用程序进程和运输层协议之间的接口,也称应用程序编程接口API ;

  • 发送端的应用将报文推给套接字;
  • 运输层负责将从套接字获得报文;

可以用门户类比套接字;

用户通过API对传输层的控制仅限于选择传输协议或设定一些参数;

进程寻址

为了一个进程能接收报文,它需要一个标识

  • 主机有唯一的32位IP地址
  • 主机上的进程标识包括IP地址和端口号

比如Web服务经常运行在80端口,而SSH服务运行在22端口上;

应用层协议

回忆协议的基本要素:交换的报文类型,报文类型的语法,字段的语义,进程何时、如何发送报文及对报文进行响应;

由RFC定义一些公共领域协议供大家使用,比如HTTP,SMTP;也有一些专用协议KaZaA;

传输层的服务

回忆协议栈知识,下层协议向上层提供服务,

运输层协议的选择的依据是应用程序服务要求,常见如下:

  1. 可靠数据传输:应用要求数据的可靠性,但是网络传输是不可靠的;选择提供可靠数据传输服务的协议时,进程将数据传给套接字后,就可以相信数据能无差错到达接收进程;但是有些应用是容忍丢失的,比如多媒体应用;
  2. 吞吐量:通常是一些带宽敏感(bandwidth-sensitive)的应用,比如多媒体;而弹性(elastic)应用能够自主决定使用的吞吐量;
  3. 定时:比如电话等,需要提供定时保证的运输层协议;
  4. 安全性:有些应用要求数据必须加密传输;

更直接地说,开发Internet应用程序,需要选择的两个运输层协议是:TCP和UDP;

它们的共同点是:都没有提供时延保证和最小带宽保证;没有提供任何加密机制;

它们的区别可以用下表概括:

特性 TCP (Transmission Control Protocol) UDP (User Datagram Protocol)
连接类型 面向连接:在数据传输前需要建立连接(三次握手),结束后终止连接。 无连接:直接发送数据,不建立或维护连接。
可靠性 可靠:保证数据按序、无差错地到达,提供错误检查、重传和确认机制。 不可靠:不保证数据到达、顺序或无差错,不提供错误检查或重传。
速度与效率 较慢:由于连接管理、流量控制和拥塞控制,开销较大,传输速度相对慢。 较快:开销小,传输速度快,适合对实时性要求高的应用。
流量控制 :通过滑动窗口等机制防止发送方淹没接收方。 :不控制发送速率,可能导致接收方过载或数据丢失。
拥塞控制 :通过算法避免网络拥塞,并在拥塞发生时减缓发送速率。 :不检测或避免网络拥塞,可能加剧拥塞。
有序传输 :通过序号确保数据包按序到达。 :数据包可能乱序到达,由应用层处理排序。
头部长度 可变:20-60字节。 固定:8字节。
广播/多播 不支持:点对点通信。 支持:适用于一对多通信。
典型应用 Web浏览 (HTTP/HTTPS), 文件传输 (FTP), 电子邮件 (SMTP/POP3/IMAP), SSH 在线游戏, 视频/音频流 (实时), VoIP (网络电话), DNS 查询, 网络监控

HTTP协议

Web层应用层协议为超文本传输协议(hypertext transfer protocol, HTTP),是Web应用的核心;遵循C/S架构,浏览器browser请求, 接收, 解释显示 Web对象,Web服务器响应请求,发送 Web对象;

Web

万维网www是一个大规模的、联机式的信息储藏所,用链接(link)的方法能非常方便地从因特网上的一个站点访问另一个站点;

  • 提供分布式服务;
  • 万维网以客户服务器方式工作。
  • 浏览器就是在用户计算机上的万维网客户程序。万维网文档所驻留的计算机则运行服务器程序(Apache, IIS),因此这个计算机也称为万维网服务器。
  • 客户程序向服务器程序发出请求,服务器程序向客户程序送回客户所要的万维网文档。
  • 在一个客户程序主窗口上显示出的万维网文档称为页面(page)。

统一资源定位符 (Uniform Resource Locator,URL)来标志万维网上的各种文档;是对可以从因特网上得到的资源的位置和访问方法的一种简洁的表示。URL 给资源的位置提供一种抽象的识别方法,并用这种方法给资源定位。只要能够对资源定位,系统就可以对资源进行各种操作,如存取、更新、替换和查找其属性。 URL 相当于一个文件名在网络范围的扩展,可以理解是与因特网相连的机器上的任何可访问对象的一个指针,一般格式如下:

  • 访问方式:ftp ,http,News 等数据访问的协议
  • 主机:存放资源的主机在因特网中的域名
  • 端口:有时可省略,比如HTTP 的默认端口号是 80;
  • 路径:有时可省略,URL 就指到因特网上的某个主页(home page);
1
<URL的访问方式>://<主机>:<端口>/<路径>  

超文本标记语言 (HyperText Markup Language)使得万维网页面的设计者可以很方便地用一个超链从本页面的某处链接到因特网上的任何一个万维网页面,并且能够在自己的计算机屏幕上将这些页面显示出来。

一个Web文档(Web page)是由Web对象组成的;

  • Web对象对应一个实际的文件,比如HTML文件,JEPG图片,Javascript文件,Css样式表文件;
  • 一个页面有一个HTML基本文件和若干引用对象;

一个Web浏览器(Web browser)是一个实现了HTTP的客户端;因此我们常把浏览器和客户等同;

一个Web服务器(Web server)是一个HTTP的服务器端;

  • 用于存储Web对象;
  • 对象通过一个URL寻址;

报文格式

HTTP报文是客户端和服务器之间交换数据的机制,主要分为两种类型:请求报文(由客户端发送)和响应报文(由服务器发送)。

所有HTTP/1.x报文都具有相似的通用结构,包括:

  1. **起始行 **(start line):一行文本,包含报文类型的基本信息,分为请求行和响应行;
  2. 头部字段 (header line):零行或多行键值对,提供关于报文的元数据,例如主机、内容类型、长度等。
  3. 空行:一个回车符和换行符,表示头部字段的结束。
  4. 报文主体:可选部分,包含实际传输的数据(如HTML文件、图片、表单数据等)。

TTP请求报文格式用于客户端向服务器请求某个资源或提交数据,其格式如下:

  • 方法:指示对资源执行的动作,如 GET(获取资源)、POST(提交数据)、HEAD(获取资源头部)、PUT(更新资源)、DELETE(删除资源)等。
  • 请求URI:标识所请求资源的统一资源标识符(URL的路径部分)。
  • HTTP版本:表示请求使用的HTTP协议版本,通常是 HTTP/1.1
  • 头部字段:提供请求的附加信息,例如:
    1. Host: 目的主机和端口号。
    2. User-Agent: 发送请求的用户代理(浏览器)信息。
    3. Accept: 客户端能够处理的媒体类型。
    4. Content-Type: 报文主体的媒体类型(如果存在报文主体)。
    5. Content-Length: 报文主体的长度(如果存在报文主体)。
  • 报文主体 (Message Body):包含客户端发送给服务器的数据,主要用于 POSTPUT 请求。
1
2
3
4
5
6
<方法> <请求URI> <HTTP版本>
<头部字段1>: <值>
<头部字段2>: <值>
...
<空行>
[报文主体]

HTTP响应报文用于服务器对客户端请求的回复,其格式如下:

  • HTTP版本:表示响应使用的HTTP协议版本。
  • 状态码(status code):一个三位数字代码,指示请求的处理结果,如 200 (OK), 301(Move Permanently), 400(Bad Request),404 (Not Found), 500 (Internal Server Error) , 505(HTTP Version Not Support)等。
  • 原因短语:状态码的简短文字描述,帮助人类理解。
  • 头部字段:提供响应的附加信息,例如:
    1. Server: 服务器软件信息。
    2. Date: 响应生成的时间。
    3. Content-Type: 响应报文主体的媒体类型。
    4. Content-Length: 响应报文主体的长度。
    5. Last-Modified: 资源的最后修改时间。
  • 报文主体:包含服务器返回给客户端的实际数据,如HTML页面内容、图片等。
1
2
3
4
5
6
<HTTP版本> <状态码> <原因短语>
<头部字段1>: <值>
<头部字段2>: <值>
...
<空行>
[报文主体]

工作流程

HTTP使用TCP作为运输层协议

  • 客户初始化一个与HTTP服务器80端口的TCP连接 (创建套接字)
  • HTTP服务器接受来自客户的TCP连接请求, 建立连接
  • Browser (HTTP client)和Web服务器 (HTTP server) 交换HTTP报文(应用层协议消息)包括HTTP请求和响应消息
  • 最后结束(或叫关闭)TCP连接

HTTP连接以下分类,对应不同的响应时间模型

  • 持久HTTP连接:在一个TCP连接上传送多个对象,所有的请求-响应经过相同的TCP连接发送;
  • 非持久HTTP连接:在一个TCP连接上只传送一个对象,每个请求-响应对通过一个单独的TCP连接上发送;

定义往返时间RTT为一个小分组从客户主机到服务器,再到客户主机花费的时间,则以下动作都需要花费一个RTT

  • 建立TCP连接;
  • 一对请求-响应消息的交互;

HTML文件传输时间单独算作传输时延;

HTTP/1.0采用非持久HTTP连接,每个对象需要两个RTT,且每个TCP连接都需要由OS分配主机资源,不利于大量客户的并发;

HTTP/1.1采用带流水线的持久HTTP连接中,服务器发送响应消息后保持连接,后续消息也在该连接上传送,用户遇到一个所有引用对象就发送请求,所有引用对象经历1个RTT;

而一类不带流水线的HTTP连接,客户必须先收到先前请求的响应消息后才能发出新的请求,每个引用对象经历一个RTT;

虽然说HTTP是一种无状态(stateless)协议,服务器不维护客户先前的状态信息;

  • 维护状态的协议比较复杂,关键在于一致性如何保证;
  • 但是一般部分网站会搭配Cookie技术一起使用,来达成维护状态的目的,以跟踪用户数据,达成会话管理,个性化推荐,跟踪分析用户行为的目的;

Cookie是服务器发送到用户Web浏览器的一小段数据。

  • 浏览器可以存储Cookie,创建新的Cookie,修改现有的Cookie,并在后续请求中将其发送回同一服务器。
  • Cookie使Web应用程序能够存储有限的数据并记住状态信息;

Cookie技术组件包括

  1. 响应报文中的一个cookie首部行;
  2. 请求报文中的一个cookie首部行;
  3. 浏览器保存的cookie文件;
  4. Web站点后端的数据库;

Cookie的工作流程如下:

  1. 服务器设置Cookie:当服务器收到HTTP请求并希望在客户端存储一些信息时,它会在HTTP响应头中包含一个或多个Set-Cookie字段。例如:

    1
    2
    3
    4
    5
    6
    HTTP/1.1 200 OK
    Content-Type: text/html
    Set-Cookie: session_id=abc123; Expires=Wed, 31 Dec 2025 23:59:59 GMT; Path=/
    Set-Cookie: user_preference=dark_mode

    [页面内容]

    这个例子中,服务器设置了两个Cookie:session_iduser_preference

  2. 浏览器存储Cookie:浏览器收到Set-Cookie头后,会根据其中的指令将Cookie存储起来。

  3. 浏览器发送Cookie:当浏览器向同一域发送后续HTTP请求时,会自动在请求头中包含之前存储的、与当前请求域和路径匹配的Cookie。服务器收到这些Cookie后,就可以识别用户并提供个性化服务。

Web缓存

Web缓存(Web cache),更常见的名字为代理服务器(proxy server),代表初始Web服务器满足HTTP请求的网络实体;

  • 一般认为Web缓存既是服务器也是客户机;
  • 设计的目的是减少对客户机请求的响应时间,减少内部网络与接入链路上的通信量,以减少Internet上的Web流量;

内容分发网络(content distribution network, CDN) 是通过网关缓存/反向代理,它们在全球部署缓存节点,以实现快速内容分发。通常由网站开发者部署,以提高网站的可伸缩性、可靠性和性能。

条件GET方法用于证实缓存器中的对象是否为最新,避免获取缓存下来的陈旧的对象副本; 缓存器:在请求报文中包含对象最后修改时间 If-modified-since: <date> 服务器: 如果对象是最新的则响应报文中不包含对象HTTP/1.0 304 Not Modified;

FTP

特点

FTP协议的主要工作是将文件从一台主机中复制到远程主机中;其中需要关注不同系统文件系统的差异性,减少不同操作系统处理文件的不兼容性;

FTP协议提供文件传送的基本服务:

  • 主要依靠TCP的可靠运输服务;
  • 采取C/S架构,一个FTP服务器可为多个多个客户进程提供服务;
  • 服务器包含一个主进程(用于处理新请求)和若干从属进程(用于处理单个请求);

设计

FTP的工作流程如下

  1. 主进程运行在端口21上,等待客户进程的连接请求;
  2. 启动从属进程来处理客户进程发来的请求。
  3. 从属进程对客户进程的请求处理完毕后即终止,但从属进程在运行期间根据需要还可能创建其他一些子进程。
  4. 回到等待状态,继续接受其他客户进程发来的请求。主进程与从属进程的处理是并发地进行。

值得注意的是,FTP协议采取两个TCP连接

  • 控制连接在整个会话期间一直保持打开,但是控制连接不用来传送文件;
  • 服务器端的控制进程在接收到 FTP 客户发送来的文件传输请求后就创建"数据传送进程"和"数据连接";
    1. 数据传送进程用来连接客户端和服务器端;
    2. 数据连接用于传输文件;
    3. 数据传送进程实际完成文件的传送,在传送完毕后关闭数据传送连接并结束运行;
  • 两个连接运行在不同的端口号上,控制连接和数据连接不会混乱
    1. 当客户进程向服务器进程发出建立连接请求时,要寻找连接服务器进程的熟知端口(21),同时还要告诉服务器进程自己的另一个端口号码,用于建立数据传送连接。
    2. 接着,服务器进程用自己传送数据的熟知端口(20)与客户进程所提供的端口号码建立数据传送连接。

这样的设计可能有如下考虑:

  • 协议更简单,易于实现;
  • 传输文件可以操作控制连接,比如发送请求终止传输;

命令 & 应答

所有命令在控制连接上以ASCII文本形式发送

命令 描述
USER <username> 指定用户名
PASS <password> 指定密码
LIST 返回当前远程目录的文件列表
RETR <filename> 获取远程主机当前目录下的1个文件(get)
STOR <filename> 存放1个文件到远程主机当前目录下(put)

下表是常见的状态码对应的短语

状态码 描述
331 Username OK, password required
125 data connection already open; transfer starting
425 Can't open data connection
452 Error writing file

以下是一个FTP控制台信息的举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[01] ftp nic.ddn.mil 
[02] connected to nic.ddn.mil
[03] 220 nic FTP server (Sunos 4.1)ready.
[04] Name: anonymous
[05] 331 Guest login ok, send ident as password.
[06] Password: abc@xyz.math.yale.edu
[07] 230 Guest login ok, access restrictions apply.
[08] ftp> cd rfc
[09] 250 CWD command successful.
[10] ftp> get rfc1261.txt nicinfo
[11] 200 PORT command successful.
[12] 150 ASCII data connection for rfc1261.txt
(128.36.12.27,1401) (4318 bytes).
[13] 226 ASCII Transfer complete.
local: nicinfo remote: rfc1261.txt
4488 bytes received in 15 seconds (0.3 Kbytes/s).
[14] ftp> quit
[15] 221 Goodbye.

这些信息的注释如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[01] 用户要用 FTP 和远地主机(网络信息中心NIC 上的主机)建立连接。 
[02] 本地 FTP 发出的连接成功信息。
[03] 从远地服务器返回的信息,220 表示"服务就绪"。
[04] 本地 FTP 提示用户键入名字。用户键入的名字
表示"匿名"。用户只需键入 anonymous 即可。
[05] 数字 331 表示"用户名正确",需要口令。
[06] 本地 FTP 提示用户键入口令。用户这时可键入
guest 作为匿名的口令,也可以键入自己的电子邮件
地址,即耶鲁大学数学系名为 xyz 的主机上的 abc。
[07] 数字 230 表示用户已经注册完毕。
[08] ""ftp>"是 FTP 的提示信息。用户键入的是将
目录改变为包含 RFC 文件的目录。
[09] 字符 CWD 是 FTP 的标准命令,
代表 Change Working Directory。
[10] 用户要求将名为 rfc1261.txt 的文件复制到
本地主机上,并改名为 nicinfo。
[11] 字符 PORT 是 FTP 的标准命令,表示要
建立数据连接。200 表示"命令正确"。
[12] 数字 150 表示"文件状态正确,即将建立数据连接"。
[13] 数字 226 是"释放数据连接"。现在一个新的本地文件已产生。
[14] 用户键入退出命令。
[15] 表明 FTP 工作结束。

Email

设计

因特网的电子邮件系统有三个重要组件

  • 用户代理(user agent):常见的用户代理有微软的Outlook,Apple Mail等,用户代理允许用户阅读,回复,转发,保存,编辑邮件消息,用户经由代理发送写好的邮件给服务器;
  • 邮件服务器(mail server):电子邮件体系的核心,每个接收方在某个邮件服务器上有一个邮箱(mailbox);邮件服务器维护一个外出报文队列(outgoing message queue),用于处理故障等;
  • 简单邮件传输协议(simple mail transfer protocol, SMTP):作为邮件的主要应用层协议,采取TCP可靠数据传输服务,实现邮件服务器之间的互发消息;

值得注意的,与HTTP协议相比,

  • SMTP采取持久连接;而HTTP对于两类连接都有设计;
  • HTTP一类典型的PULL协议,而SMTP是典型的PUSH协议;
  • 都有ASCII命令和应答交互,状态码的设计;
  • HTTP把Web对象封装到HTTP消息中,而SMTP将邮件中的对象置于同一个邮件消息的多目部分发送;

SMTP

客户采用TCP来将邮件消息直接发送到服务器端口号25,有如下三个步骤

  • 握手:介绍双方基本信息,其中命令和应答交互的交互方式仍为ASCII文本和状态码短语;
  • 邮件消息的传输:SMTP规定必须是7bitASCII码,这是一个比较陈旧的特性;
  • 结束

一个邮件的发送和接收过程如下图所示

  1. 发信人调用用户代理来编辑要发送的邮件。用户代理用 SMTP 把邮件传送给发送端邮件服务器。
  2. 发送端邮件服务器将邮件放入邮件缓存队列中,等待发送。
  3. 运行在发送端邮件服务器的 SMTP 客户进程,发现在邮件缓存中有待发送的邮件,就向运行在接收端邮件服务器的 SMTP 服务器进程发起 TCP 连接的建立。若对方没有开机,则会稍后尝试;
  4. TCP 连接建立后,SMTP 客户进程开始向远程的 SMTP 服务器进程发送邮件。当所有的待发送邮件发完了,SMTP 就关闭所建立的 TCP 连接。
  5. 运行在接收端邮件服务器中的 SMTP 服务器进程收到邮件后,将邮件放入收信人的用户邮箱中,等待收信人在方便时进行读取。
  6. 收信人在打算收信时,调用用户代理,使用 POP3(或 IMAP)协议将自己的邮件从接收端邮件服务器的用户邮箱中的取回(如果邮箱中有来信的话)。

指令 & 应答

下表是常见的指令对应的短语含义

命令 说明 备注
HELO 邮件服务器标志用户身份 发送者欺骗说谎,伪造合法服务器身份
MAIL FROM 指定发件人地址 伪造成合法用户身份
RCPT TO 标志单个收件人地址,可有多个 RCPT TO 伪造收件人地址,如使用字典攻击或利用工具收集合法用户的邮箱地址
DATA 初始化数据传输并以 CRLF 结束 基于内容的垃圾邮件
QUIT 结束会话

邮件消息的格式

SMTP是用于交换邮件消息的协议,RFC822定义了文本邮件格式的标准。一个RFC822消息包含:

  • 头部 (Headers):由一系列"字段名: 字段体"对组成,每个字段占据一行,用于描述邮件的元数据,例如发件人(From)、收件人(To)、主题(Subject)、日期(Date)等。
    • 字段名:标识字段的类型(如 From, To, Subject)。
    • 字段体:包含字段的实际内容。
    • 空行:一个空行(CRLF)表示头部的结束,将头部与邮件体分开。
  • 邮件体 (Body):包含实际的邮件内容,可以是纯文本。RFC822最初只支持7位ASCII文本。

多用途Internet邮件拓展(Multipurpose Internet Mail Extensions, MIME)在RFC2045中提出,用于邮件内容的多媒体拓展,它扩展了RFC822的限制,允许邮件包含:

  • 非ASCII字符集:支持除ASCII之外的字符集,如UTF-8,使得邮件可以包含各种语言的文本。
  • 非文本内容:支持在邮件中嵌入图片、音频、视频、应用程序文件等多种二进制数据类型。
  • 多部分邮件:允许将邮件内容分成多个"部分"(parts),每个部分可以有不同的内容类型和编码方式,这些部分可以按层级结构组织。

MIME通过在邮件头部添加额外的字段来描述邮件内容的类型和编码,主要包括:

  • MIME-Version:指示邮件遵循MIME标准,通常为 1.0
  • Content-Type:描述邮件或邮件部分的媒体类型和子类型(如 text/plain, text/html, image/jpeg, application/pdf, multipart/mixed 等),并可包含参数,如字符集 (charset)。
  • Content-Transfer-Encoding:指定邮件体或部分内容的编码方式,以确保二进制数据能通过只支持文本的邮件系统传输(如 base64, quoted-printable, 7bit, 8bit, binary)。
  • Content-Disposition:指示邮件内容的呈现方式,是作为附件 (attachment) 还是内联显示 (inline)。

邮件访问协议

邮件访问协议设计为用户代理从邮件服务器获取邮件消息的任务,主流的协议有如下几类:

  • POP: 邮局协议(Post Office Protocol )[RFC 1939]110端口号,需要代理与服务器的身份认证并下载邮件消息
  • IMAP: Internet Mail Access Protocol [RFC 1730],更多功能特征 允许用户像对待本地邮箱那样操纵远程邮箱的邮件
  • HTTP: Hotmail , Yahoo! Mail, etc.

例如在POP3协议中,身份认证阶段(authorization phase)可能包含如下命令和应答

  • 客户命令: user usernamepass password
  • 服务器响应:+OK-ERR
1
2
3
4
5
S: +OK POP3 server ready 
C: user bob
S: +OK
C: pass hungry
S: +OK user successfully logged on

传输阶段(transaction phase)可能包括如下过程

  • list: 列出邮件编号
  • retr: 按编号取邮件
  • dele: 删除
  • quit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
C: list 
S: 1 498
S: 2 912
S: .
C: retr 1
S: <message 1 contents>
S: .
C: dele 1
C: retr 2
S: <message 1 contents>
S: .
C: dele 2
C: quit
S: +OK POP3 server signing off

POP3的会话是无状态的,POP3还区分如下两类模式,

  • Download-and-delete换客户端后不能再读邮件
  • Download-and-keep在不同客户机上的邮件拷贝

而IMAP允许用户直接在服务器的各文件夹中管理邮件消息

  • 保存所有邮件消息在服务器;
  • IMAP跟踪用户会话的状态信息;
  • 文件夹和邮件消息IDs与文件夹名字的映射

DNS

互联网上的主机一般通过便于记忆的主机名(hostname)或者IP地址来标识,域名系统(domain name system,DNS)负责将主机名映射到IP地址,其组件如下:

  • 一个有分层的DNS服务器实现的分布式数据库;
  • 一个使得主机查询数据库的应用层协议;

DNS必须是分布式的,而不是集中式的,因为集中式可能带来的单点故障,巨大访问量,难以维护导致的不可拓展问题;

服务

一个DNS服务器通常是运行在软件BIND(Berkeley Internet Name Domain)的UNIX机器;DNS规范中在RFC1034中定义

  • 它依靠的运输层协议是UDP;
  • 运行在53号端口上;
  • 采用C/S架构,但不直接和用户打交道,而是为其他应用程序提供域名解析的功能,为其他应用层协议使用;

简而言之,DNS服务器提供的服务可概括为

  1. 主机名到IP地址的映射;
  2. 主机别名:一个主机拥有一个规范主机名和多个主机别名;
  3. 邮件服务器别名;
  4. 负载分配:通过冗余服务器实现,将一个IP地址结合对应于同一个规范主机别名;

有三种类型的DNS服务器,这些大量的DNS服务器以层次的方式组织成分布式数据库,注意没有一台DNS服务区具有Internet上所有主机的映射;如图所示

  • 根DNS服务器(root name):根名字服务器负责记录顶级域名服务器的信息
  • 顶级域DNS服务器(top-level domain, TLD):负责顶级域名 com, org, net, edu, etc, 和所有国家的顶级域名 uk, fr, ca, jp.比如Network solutions 公司维护com顶级域的TLD服务器和Educause 公司维护edu顶级域的 TLD服务器
  • 权威DNS服务器:多数大学和公司维护它们的基本权威DNS服务器。在因特网上具有公共可访问主机(如Web服务器和邮件服务器)的每个组织机构必须提供公共可访问的DNS记录,这些记录将这些主机的名字映射为IP地址。组织机构的权威DNS服务器负责保存这些DNS记录。

本地DNS服务器一般不认为属于层次结构中,每个ISP都会有一个DNS服务器,也是默认服务器;当主机发出DNS请求时,将首先发往本地DNS服务器,起代理的作用,转发请求到层次结构中;

层次树命名

连接在Internet上的主机(包括路由器)对应一个域名(domain name);由若干分量组成,用点隔开*.三级域名.二级域名.顶级域名

这种层次结构对应了DNS服务器的层次结构;这样的结构解决了扩展性问题;

一个客户机查询主机名IP地址的自顶向下的示例过程和示例图如下:

  1. 客户机递归查询根服务器得到dns.edu DNS服务器
  2. 客户机迭代查询dns.edu 服务器得到dns.cs.umass.edu 服务器
  3. 客户机迭代查询dns.cs.umass.edu 服务器得到gaia.cs.umass.edu的IP地址

缓存

DNS缓存(DNS caching)技术用于改善时延性能和减少Internet上传输的DNS报文数量,直接的结果就是根DNS服务器不会被大量经常访问;

  • 一旦名字服务器获得DNS映射, 它将缓存该映射到局部内存
  • 服务器在一定时间后将丢弃缓存的信息
  • 本地DNS服务器可以缓存TLD服务器的IP地址

IETF在RFC 2136中正在设计动态更新/通报机制;

记录

DNS作为数据库的一种,我们也关心其记录是什么格式的,有关内容记录在RFC1034中;

资源记录(resource record,RR)存储在DNS服务器中,其格式为具有如下形式的四元组:(NAME, VALUE, TYPE, TTL)

TTL (Time To Live)是该记录的生存时间,指示该记录在DNS服务器中缓存多长时间(秒)。其余的字段的有一种对应关系,如下表所示

类型 (Type) 名称 (Name) 值 (Value) 描述 (Description) 示例 (Example)
A 主机名 IP地址 将主机名映射到对应的IP地址 (gaia.cs.umass.edu, 128.119.245.12, A, TTL)
NS 权威DNS服务器的主机名 标识该域的权威DNS服务器 (foo.com, dns.foo.com, NS, TTL)
CNAME 别名主机名 规范主机名 将别名主机名映射到其规范主机名。别名主机名不能有其他记录 (www.foo.com, foo.com, CNAME, TTL)
MX 邮件服务器的别名 邮件服务器的规范主机名 允许一个公司的邮件服务器和Web服务器使用同一个别名 (foo.com, mail.bar.blop.com, MX, TTL)

这些不同类型的记录对应不同场景下在DNS数据库插入记录的操作

  • 如果你想在注册登记机构注册你的域名example.com,则 需要提供你自己的基本权威DNS服务器和辅助权威DNS服务器的名字和IP地址

    1
    2
    (example.com, dns1.example.com, NS)
    (dns1.example.com, 212.212.212.1, A)
  • 建立一个网站,则可以将网址www.example.com以类型A的方式记录到你的权威DNS服务器dns1.example.com中。

  • 建一个邮件服务器,则可以将mail.example.com以类型MX的方式记录到你的权威DNS服务器dns1.example.com中。

消息

DNS的查询报文和应答报文具有相同的格式,如图所示,前12字节为首部区域;

  • 标识符:16比特,查询和应答报文使用相同的标识符;
  • 标志:有若干标识位代表不同功能
    1. 查询/应答-0/ 1
    2. 查询希望是/非递归查询-1/0
    3. 应答可/否获得(支持)递归查询-1/0
    4. 应答是/否来自权威名字服务器-1/ 0
  • 问题部分:查询的Name, type;
  • 回答部分:对于查询,应答的资源记录,可以多个资源记录,由于可以有多个IP地址
  • 权威部分:权威名字服务器的其他资源记录
  • 附加信息部分:其他有帮助的记录.

P2P

有一类非常自然的P2P应用,比如发布操作系统的更新,游戏的补丁;这些用户数量巨大,全部交由服务器是不现实的,在P2P文件分发中,每个对等方向其他对等方发送它接收到文件的部分;

设计

点对点网络(Peer-to-Peer, P2P)是一种去中心化的网络架构,其中对等方直接相互交互,无需依赖中央服务器或中心机构。

在P2P网络中,每个对等方既充当客户端,也充当服务器,从而能够直接与其他对等方共享资源和服务。

这样的设计带来了如下的特点:

  • 去中心化
  • 资源共享
  • 直接通信
  • 可伸缩性
  • 容错性和冗余
  • 隐私和安全性......

内容分发时间

在文件分发场景中,P2P架构与传统的客户端-服务器(C/S)架构在内容分发时间上存在显著差异。假设要分发一个大小为 F 比特的文件给 N 个对等方。

在C/S架构中,文件分发由一个中央服务器独立完成,所有对等方都从该服务器下载文件。分发时间 Dcs的下限由以下两个因素决定:

  • 服务器上传能力限制:服务器必须将文件的 N 份副本上传给 N 个对等方。如果服务器的上传速率为 Us,则至少需要 N * F / Us 的时间。
  • 最慢客户端下载能力限制:所有 N 个对等方都必须下载文件的完整副本。如果所有对等方中下载速率最慢的为 Dmin,则最慢的对等方至少需要 F / Dmin 的时间来下载文件。

综合以上两点,客户端-服务器架构下的最小分发时间为:

对于足够大的 NDcs 倾向于由服务器上传能力限制,即 N * F / Us。这意味着分发时间将随对等方数量 N 线性增长,这在用户数量庞大时会成为瓶颈。

在P2P架构中,每个对等方在下载文件的同时,也可以将已下载的部分上传给其他对等方,从而协助分发。分发时间 Dp2p(P2P Distribution Time)的下限由以下三个因素决定:

  • 服务器上传能力限制:与C/S架构类似,服务器至少需要将文件初始上传一次,时间为 F / Us
  • 最慢对等方下载能力限制:与C/S架构类似,最慢的对等方至少需要 F / Dmin 的时间来下载文件。
  • 整个系统总上传能力限制:为了将文件的 N 份副本分发给 N 个对等方,系统总共需要传输 N * F 比特的数据。这些数据由服务器和所有对等方共同上传。如果系统总上传速率为 Utotal(即服务器上传速率 Us 加上所有对等方上传速率 Ui 的总和),则至少需要 N * F / Utotal 的时间。

综合以上三点,P2P架构下的最小分发时间为:

其中,

image-20250608181935649

P2P网络优缺点

P2P网络相对于传统的客户端-服务器架构具有以下优点和缺点:

优点 (Advantages) 缺点 (Disadvantages)
去中心化和弹性:没有单点故障,网络更具弹性。 缺乏集中控制:难以管理和协调网络活动,难以执行一致的策略并确保数据完整性。
易于扩展:随着对等方数量增加,可用资源和能力随之增长,可处理更大的工作负载。 网络管理复杂性:对等方责任均等,网络管理任务(如寻址、安全性、性能优化)必须在参与者之间分配,需要额外的协调和努力。
高效资源利用:通过在多个对等方之间分配负载,提高资源利用率。 依赖对等方可用性:资源和服务的可用性取决于对等方的活跃参与,如果大量对等方离线或不活跃,可能会影响性能和可用性。
成本节约:无需昂贵的专用服务器或集中式基础设施,设置和维护成本更低。 性能和效率可变性:P2P网络的性能受参与对等方的数量和质量、可用资源以及网络拓扑等因素的影响,可能导致不可预测的行为。
直接通信和更快的内容交付:对等方之间直接通信,消除中介,实现更快的交付和实时交互。 安全风险:如果未采取适当预防措施,P2P网络可能会引入安全风险。恶意对等方可能利用网络中的漏洞发起攻击或分发恶意内容。
增强隐私和安全性:对等方之间直接通信可以加密,保护数据机密性,降低单点攻击的脆弱性。 法律和版权问题:P2P网络与版权侵权和非法共享受版权保护保护材料相关联。虽然P2P技术本身不违法,但它可能促进未经授权的共享,从而引发法律和道德问题。

集中式和非集中式搜索

集中式搜索:Napster

Napster是一个早期的P2P文件共享服务,它使用一个中心服务器来维护所有在线用户的共享文件列表。当用户想要查找文件时,他们会向中心服务器发送查询。服务器返回包含该文件的用户列表,然后用户可以直接从这些用户下载文件。

非集中式搜索:Gnutella

Gnutella是一个全分布式的P2P网络协议,没有集中式服务器。它采用查询洪泛(query flooding)机制来查找文件。

  • 工作原理:当一个对等方需要查找文件时,它会向其直接连接的对等方发送查询报文。这些对等方会进一步转发该报文给它们的连接对等方,直到达到某个跳数限制或找到文件。匹配的对等方会发送 QueryHit 报文,该报文会沿着反向路径传回发起查询的对等方。
  • 覆盖网络(Overlay Network):Gnutella网络中的所有活跃对等方及其TCP连接构成了一个覆盖网络(逻辑图),这些连接不是物理通信链路。通常,一个对等方在覆盖网络中连接的节点数量少于10个。
  • 可扩展性:为了限制查询洪泛带来的网络负载,Gnutella通常采用限范围泛洪(Limited-scope flooding)机制,即查询报文只在有限的跳数内转发。
  • 加入对等方:新的对等方(如对等方X)加入Gnutella网络时,它需要发现网络中的其他对等方。通常通过使用一个已知的对等方列表。X会尝试与列表上的对等方建立一条TCP连接,直到与某个对等方Y成功连接。X向Y发送一个 Ping 报文;Y转发该 Ping 报文。所有的对等方接收 Ping 报文并响应一个 Pong 报文。X接收到许多 Pong 报文。然后能同某些其他对等方建立TCP连接。

image-20250608182213049

混合式架构:KaZaA

KaZaA是一种流行的文件共享P2P应用,它采用了混合式的P2P架构,结合了集中式和去中心化的特点。它引入了"超级对等方"(Super-peers)或"组长"的概念,这些超级对等方充当了网络的局部索引服务器。

层次结构:每个对等方要么被指派为"组长"(Super-peer),要么被指派给一个"组长"作为其"子对等方"。

  • 对等方与组长之间的连接:对等方与它们的组长之间建立TCP连接。
  • 组长之间的连接:组长之间也建立TCP连接,形成一个高层级的覆盖网络。

内容管理:组长负责维护其所有子对等方共享的内容的索引。当子对等方共享文件时,它们会将文件信息(如文件名、大小、哈希值等)报告给其组长。

文件查询

  1. 客户端(对等方)向其组长发送关键词查询。
  2. 组长响应匹配的逐项信息,包括元数据、文件的散列值和持有该文件的对等方的IP地址。
  3. 如果组长没有找到匹配项,它可能会将查询转发给其他组长,其他组长会响应匹配。

文件下载:客户端选择要下载的文件后,直接向持有该文件的对等方发送HTTP请求(使用文件的哈希值作为标识符)。

下载优化机制

  • 请求排队:限制对等方并行上传的数量,新的下载请求进入队列等待。
  • 激励优先权:根据不同的上传/下载比例优先服务贡献大的对等方,鼓励用户共享资源。
  • 并行下载:将一个文件分成若干段,从多个对等方并行下载,以提高下载速度。

CDN

HTTP stream & DASH

传统的流媒体(如RTP/RTCP)通常需要专门的流媒体服务器和协议来传输音视频内容。而HTTP流媒体是利用标准的HTTP协议来传输多媒体内容的一种方式。它的主要优势在于可以复用现有的Web基础设施,无需部署额外的流媒体服务器,这大大简化了内容分发。

HTTP流媒体的核心思想是将音视频内容分割成小的、独立的媒体片段,然后通过HTTP协议逐步下载这些片段并在客户端进行播放。这种方式使得内容分发能够充分利用HTTP缓存、CDN等现有技术。

DASH(Dynamic Adaptive Streaming over HTTP),用于通过HTTP传输流媒体内容。它的主要特点是"自适应",这意味着客户端可以根据网络带宽、CPU负载等条件动态地选择不同质量(比特率、分辨率)的媒体片段进行下载和播放。

原始的音视频内容会被编码成多种不同比特率和分辨率的版本。每个版本再被分割成许多小的、固定或可变长度的媒体片段(通常是几秒钟)。

**媒体演示描述 (Media Presentation Description, MPD):**一个XML文件作为告示文件,存储在HTTP服务器中,包含了关于所有可用媒体片段的元数据,包括:

  • 不同质量版本的URL。
  • 每个片段的时长。
  • 编解码器信息。
  • 内容版权信息等。

客户端首先下载MPD文件,然后根据其中的信息来决定下载哪些媒体片段。客户端适应性播放:

  • 客户端持续监测当前的网络带宽状况和设备性能。
  • 根据监测结果,客户端会智能地选择下载最适合当前条件的媒体片段。例如,如果网络带宽下降,客户端会自动切换到低比特率的视频片段,以避免卡顿;反之,如果带宽充足,则切换到高比特率以提供更好的观看体验。
  • 客户端会维护一个缓冲区,预先下载一些片段,以应对网络波动。

CDN

内容分发网络(Content Delivery Network, CDN) 是一个地理上分散的服务器网络,用于高效地向用户分发内容。主要为视频流,网站加速,文件下载等公司采用;它们有些部署自己的CDN,有些采用第三方的服务;

CDN 的工作原理:

  1. 缓存内容:当用户首次请求某个内容(如图片、视频、网页、JavaScript 文件等)时,CDN 会从原始服务器(源站)获取该内容,并将其缓存到离用户最近的CDN节点(边缘服务器)上。
  2. 就近分发:大多数CDN利用DNS进行重定向请求,意思是后续用户再次请求相同内容时,如果该内容已经在附近的CDN节点上缓存,CDN 会直接从该节点提供服务,而无需回源到原始服务器。
  3. 流量管理:CDN 能够智能地将用户请求路由到性能最佳的边缘服务器,这通常是地理位置最近或负载最轻的服务器。
  4. 负载均衡:通过将流量分散到多个服务器上,CDN 可以有效地分担源站的压力,防止因高并发访问导致服务器过载。

CDN的部署遵循集群选择策略,动态地将用户定向到CDN中地某个数据中心地机制;可以是基于地理的,或者基于流量的;

套接字编程

套接字(Socket)是网络编程中用于实现进程间通信的一种抽象机制。它作为应用程序与网络协议栈之间的接口,允许程序通过网络发送和接收数据。在计算机网络中,不同主机上的进程通过套接字相互通信。

每个套接字都绑定到一个IP地址和端口号,从而唯一标识网络上的一个进程。

  • IP地址:标识主机在网络中的位置。在Python中用socket.AF_INET作为参数代表IPv4;
  • 端口号:标识主机上运行的特定进程或服务。

Stream

流套接字(streaming sockets)使用TCP协议。

  • 提供面向连接的、可靠的有序的基于字节流的数据传输。
  • Python中使用SOCK_STREAM作为初始化参数传入;
  • 适用于需要高可靠性、对数据完整性和顺序有严格要求的应用,如Web浏览(HTTP)、文件传输(FTP)和电子邮件(SMTP)。

客户端和服务端基本步骤如下:

服务器端基本步骤:

  1. 创建套接字:server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  2. (服务端)绑定地址和端口:server_socket.bind(('127.0.0.1', 12345)),用户端不需要;TCP监听连接:server_socket.listen(5);TCP接受连接:client_socket, client_address = server_socket.accept()用于获得客户端套接字(和客户端的地址。

    (用户端)连接服务器:client_socket.connect(('127.0.0.1', 12345))

  3. 发送字节数据:client_socket.sendall(b"Hello from server")

  4. 接收字节数据:data = client_socket.recv(1024)

  5. 关闭套接字:server_socket.close()

Datagram

数据报套接字 (Datagram Sockets)使用UDP协议。

  • 提供无连接的、不可靠的无序的数据传输。
  • Python中使用SOCK_DGRAM作为初始化参数传入;
  • 适用于对实时性要求高、容忍少量数据丢失的应用,如在线游戏、VoIP(网络电话)和DNS查询。

服务器端和用户端基本步骤:

  1. 创建套接字:server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

  2. (服务端)绑定地址和端口:server_socket.bind(('127.0.0.1', 12345))

    (客户端)无操作

  3. 接收和发送数据:使用 recvfrom() 接收数据(同时获取发送方的地址),使用 sendto() 发送数据(需要指定目标地址)。

    1
    2
    data, client_address = server_socket.recvfrom(1024)
    server_socket.sendto(b"Hello back", client_address)
  4. 关闭套接字server_socket.close()