网络应用的基本原理(Principles of Network Applications)
网络应用架构(Application Architectures)
网络应用架构是指网络应用的组织和设计方式,它决定了应用中不同组件之间的交互模式和通信方式。课件中介绍了两种主要的网络应用架构:客户端-服务器架构(Client-Server)和对等架构(Peer-to-Peer, P2P)。以下是对这两种架构的详细讲解:
客户端-服务器架构(Client-Server Architecture)
客户端-服务器架构是一种集中式的网络应用架构,其中服务器是核心组件,客户端依赖服务器来获取资源和服务。这种架构的特点如下:
服务器(Server)
- 始终在线(Always-On Host):服务器通常是始终运行的,不会频繁关机。
- 固定IP地址(Permanent IP Address):服务器通常拥有固定的IP地址,便于客户端访问。
- 可扩展性(Scalability):为了应对大量客户端的请求,服务器可以部署在数据中心(Data Centers),通过增加服务器数量或提升服务器性能来扩展服务能力。
客户端(Client)
- 与服务器通信(Communicate with Server):客户端通过网络与服务器进行通信,获取资源和服务。
- 间歇性连接(Intermittently Connected):客户端可能不会一直在线,而是根据需要与服务器建立连接。
- 动态IP地址(Dynamic IP Addresses):客户端的IP地址可能是动态分配的,每次连接时IP地址可能会变化。
- 不直接通信(No Direct Communication):客户端之间不直接通信,所有交互都通过服务器进行。
交互模式(Interaction Model)
- 客户端向服务器发送请求(Request),服务器处理请求后返回响应(Response)。
- 客户端是服务的请求者,服务器是服务的提供者。
对等架构(Peer-to-Peer, P2P Architecture)
对等架构是一种去中心化的网络应用架构,其中每个节点(Peer)既是服务的请求者,也是服务的提供者。这种架构的特点如下:
节点(Peer)
- 无固定服务器(No Always-On Server):没有始终在线的中心服务器,每个节点都是对等的。
- 直接通信(Direct Communication):任意两个节点可以直接通信,无需通过中心服务器。
- 请求与提供服务(Request and Provide Services):节点可以向其他节点请求服务,同时也可以为其他节点提供服务。
- 自我扩展性(Self-Scalability):新节点的加入会带来新的服务容量,同时也带来新的服务需求。
- 间歇性连接(Intermittently Connected):节点可能不会一直在线,而是根据需要与其他节点建立连接。
- 动态IP地址(Dynamic IP Addresses):节点的IP地址可能是动态分配的,每次连接时IP地址可能会变化。
交互模式(Interaction Model)
- 节点之间直接建立连接,进行数据交换。
- 没有固定的客户端和服务器角色,每个节点都可以根据需要扮演不同的角色。
进程通信与套接字(Processes Communicating & Sockets)
进程通信的基本概念(Basic Concepts of Process Communication)
- 进程(Process):进程是运行在主机内的程序实例。每个进程都有自己的内存空间和执行状态。
- 同一主机内的进程通信(Inter-Process Communication within the Same Host):
- 在同一主机内,两个进程可以通过操作系统提供的进程间通信机制(Inter-Process Communication, IPC)进行通信。
- 常见的IPC机制包括管道(Pipes)、共享内存(Shared Memory)、消息队列(Message Queues)、信号(Signals)等。
- 不同主机内的进程通信(Process Communication between Different Hosts):
- 在不同主机之间,进程通过网络通信进行交互。
- 进程之间通过发送和接收消息(Messages) 来传递数据。
客户端和服务器进程(Client and Server Processes)
- 客户端进程(Client Process):
- 客户端进程是发起通信的一方。
- 它主动向服务器进程发送请求,请求某种服务或资源。
- 服务器进程(Server Process):
- 服务器进程是等待被联系的一方。
- 它被动地监听客户端的请求,并在收到请求后提供相应的服务。
- P2P架构中的角色(Roles in P2P Architectures):
- 在P2P架构中,每个节点既可以是客户端,也可以是服务器。
- 每个节点既可以发起通信,也可以响应其他节点的通信请求。


应用层协议与传输层服务(App-layer Protocols and Transport Layer Services)
这一节主要介绍了应用层协议的定义、传输层服务的需求,以及如何通过传输层协议(如TCP和UDP)实现应用层协议的通信。以下是详细内容:
应用层协议的定义(App-layer Protocol Definition)
应用层协议定义了网络应用中进程之间如何进行通信。它包括以下几个方面:
消息类型(Types of Messages)
- 请求(Request):客户端向服务器发送的请求某种服务或资源的消息。
- 响应(Response):服务器对客户端请求的回应消息。
消息语法(Message Syntax)
- 字段(Fields):消息中包含的各个部分,如请求行、头字段、正文等。
- 字段分隔(Field Delineation):如何区分消息中的不同字段,例如通过特定的分隔符(如换行符、冒号等)。
消息语义(Message Semantics)
- 字段含义(Meaning of Fields):每个字段的具体含义,例如请求行中的方法(如GET、POST)、响应行中的状态码等。
通信规则(Rules for Communication)
- 发送和响应规则(Rules for Sending and Responding):定义了进程何时以及如何发送和响应消息。例如,HTTP协议规定了客户端如何发起请求,服务器如何响应请求。
开放协议与专有协议(Open vs. Proprietary Protocols)
- 开放协议(Open Protocols):
- 在RFC(Request for Comments)文档中定义,允许不同厂商的软件之间实现互操作性。
- 示例:HTTP、SMTP。
- 专有协议(Proprietary Protocols):
- 由特定公司或组织开发,不公开其详细规范。
- 示例:Skype、Zoom。
应用程序对传输层服务的需求(Transport Layer Services Needed by Applications)
不同的网络应用对传输层服务的需求各不相同

时延(Timing)
- 低延迟需求(Low Delay Requirement):
- 一些实时应用(如互联网电话、在线游戏)要求低延迟,以保证交互的实时性。
- 这通常需要UDP协议,因为它减少了传输层的开销。
- 高延迟容忍(High Delay Tolerance):
- 一些非实时应用(如文件下载)对延迟的容忍度较高,更关注数据的完整性和可靠性。
吞吐量(Throughput)
- 高吞吐量需求(High Throughput Requirement):
- 一些多媒体应用(如视频流媒体)需要较高的吞吐量来保证数据的连续传输。
- 这通常需要TCP协议,因为它可以通过拥塞控制机制动态调整传输速率。
- 弹性应用(Elastic Applications):
- 一些应用(如网页浏览)对吞吐量的要求不固定,可以根据网络条件动态调整。
安全性(Security)
- 加密(Encryption):保护数据在传输过程中的隐私。
- 数据完整性(Data Integrity):防止数据在传输过程中被篡改。
- 端点认证(Endpoint Authentication):确保通信双方的身份是可信的。
应用层协议与传输层协议的关系(Application and Transport Protocols)
常见的应用层协议及其传输层协议

传输层协议的特点(Characteristics of Transport Layer Protocols)
- TCP(传输控制协议):
- 提供可靠的数据传输服务,确保数据的完整性和顺序。
- 适用于对可靠性要求高的应用,如文件传输、Web浏览等。
- UDP(用户数据报协议):
- 提供不可靠但快速的数据传输服务,不保证数据的可靠性和顺序。
- 适用于对实时性要求高的应用,如音频流媒体、在线游戏等。
传输层安全性(Transport Layer Security, TLS)
- TLS的作用(Role of TLS):
- 提供加密的TCP连接,确保数据在传输过程中的隐私和完整性。
- 提供端点认证,防止中间人攻击。
- TLS的实现(Implementation of TLS):
- TLS在应用层实现,应用程序通过TLS库(如OpenSSL)使用TLS。
- TLS库底层使用TCP协议,将明文数据加密后通过网络传输。
- TLS还提供消息完整性和认证功能,确保数据在传输过程中不被篡改。
Web 和 HTTP(Web and HTTP)
Web页面的组成(Composition of a Web Page)
- Web页面由多个对象组成:
- 每个对象可以是一个HTML文件、JPEG图片、Java小程序、音频文件等。
- 一个Web页面通常包含一个基础HTML文件,该文件中引用了其他多个对象(如图片、CSS文件、JavaScript文件等)。
- 每个对象都可以通过一个**URL(统一资源定位符)**来访问。例如:
http://www.someschool.edu/someDept/pic.gif
www.someschool.edu
是主机名/someDept/pic.gif
是路径名
HTTP协议概述(HTTP Overview)
- HTTP(超文本传输协议):
- Web的应用层协议。
- 基于客户端-服务器模型。
- 客户端:浏览器,负责请求、接收并显示Web对象。
- 服务器:Web服务器,负责响应客户端的请求并发送Web对象。


HTTP连接类型(HTTP Connection Types)

非持久连接(Non-Persistent HTTP)
- 每个TCP连接只能传输一个对象,传输完成后立即关闭连接
- 需要2个往返时间(RTTs)来获取每个对象
- 第一个RTT用于建立TCP连接。
- 第二个RTT用于发送HTTP请求并接收HTTP响应。
- 操作系统对每个TCP连接的开销
- 每次建立和关闭TCP连接都需要操作系统分配和释放资源,这会增加系统开销。
- 浏览器通常会并行打开多个TCP连接来获取引用的对象
- 由于每个对象都需要单独的TCP连接,浏览器为了提高效率,会同时打开多个TCP连接来并行获取多个对象(如图片、CSS文件等)。这会增加服务器的负载和网络的复杂性。




HTTP 请求(Request)
HTTP 请求是客户端(如浏览器)向服务器发送的请求信息,用于获取资源或执行操作。它的结构通常包括以下部分:

请求行的格式为:请求方法 URL HTTP版本
,例如:
|
|
请求头(Header Lines)
请求头包含多个字段,用于向服务器提供关于请求的额外信息。常见的请求头字段包括:
- Host:指定请求的主机名和端口号,例如 Host: www.example.com
。
- User-Agent:标识客户端的类型和版本,例如 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
。
- Accept:指定客户端可以接受的响应内容类型,例如 Accept: text/html,application/xhtml+xml
。
- Accept-Language:指定客户端偏好的语言,例如 Accept-Language: en-us,en;q=0.5
。
- Accept-Encoding:指定客户端支持的压缩格式,例如 Accept-Encoding: gzip,deflate
。
- Connection:指示是否保持连接,例如 Connection: keep-alive
。
请求头字段的格式为:字段名: 字段值
,每个字段占一行,字段之间用回车符(\r\n
)分隔。
请求正文(Body)
对于某些请求方法(如 POST 和 PUT),请求正文用于携带要提交到服务器的数据。例如,表单数据可以通过请求正文发送到服务器。正文的内容类型由 Content-Type
请求头字段指定。
请求样例
|
|
HTTP 响应(Response)
HTTP 响应是服务器对客户端请求的回复,它的结构通常包括以下部分:

状态行(Status Line)
状态行是 HTTP 响应的第一行,它包含三个部分:
- HTTP 版本:例如
HTTP/1.1
。 - 状态码(Status Code):一个三位数字,表示请求的处理结果。常见的状态码包括:
- 200 OK:请求成功,服务器返回了请求的资源。
- 301 Moved Permanently:请求的资源已被永久移动到新的位置。
- 400 Bad Request:请求格式错误,服务器无法理解。
- 404 Not Found:请求的资源在服务器上未找到。
- 500 Internal Server Error:服务器内部错误。
- 状态描述(Reason Phrase):对状态码的简短描述,例如
OK
或Not Found
。
状态行的格式为:HTTP版本 状态码 状态描述
,例如:
|
|
响应头(Header Lines)
响应头包含多个字段,用于向客户端提供关于响应的额外信息。常见的响应头字段包括:
- Date:服务器生成响应的日期和时间,例如
Date: Sun, 26 Sep 2010 20:09:20 GMT
。 - Server:服务器的软件名称和版本,例如
Server: Apache/2.0.52 (CentOS)
。 - Content-Type:响应正文的 MIME 类型,例如
Content-Type: text/html; charset=ISO-8859-1
。 - Content-Length:响应正文的长度,以字节为单位,例如
Content-Length: 2652
。 - Connection:指示是否保持连接,例如
Connection: Keep-Alive
。
响应头字段的格式与请求头类似,也是 字段名: 字段值
,每个字段占一行。
响应正文(Body)
响应正文是服务器返回给客户端的实际数据,例如 HTML 页面、图片、JSON 数据等。正文的内容类型由 Content-Type
响应头字段指定。
响应示例
|
|
Http Cookies
Cookies 是一种用于在客户端和服务器之间保持状态的技术。HTTP 协议本身是无状态的,即每次请求和响应都是独立的,服务器不会记录之前与客户端的交互信息。而 Cookies 可以解决这个问题,它允许服务器在客户端存储一些数据,以便在后续的请求中能够识别客户端。
Cookies 的四个组成部分
-
HTTP 响应中的
Set-Cookie
头 当服务器希望在客户端设置一个 Cookie 时,它会在 HTTP 响应中添加一个Set-Cookie
头。 这里,user_id=12345
是 Cookie 的名称和值,Expires
指定了 Cookie 的过期时间,Path
和Domain
指定了 Cookie 的作用范围。1
Set-Cookie: user_id=12345; Expires=Wed, 09 Jun 2021 10:18:14 GMT; Path=/; Domain=example.com
-
HTTP 请求中的
Cookie
头 客户端(如浏览器)在后续的请求中,会将之前收到的 Cookie 信息通过Cookie
头发送回服务器。服务器通过解析这个头,可以识别客户端的身份或状态。1
Cookie: user_id=12345
-
客户端的 Cookie 文件 浏览器会在本地存储收到的 Cookie,通常保存在一个专门的文件中。这些 Cookie 由浏览器管理,浏览器会根据 Cookie 的属性(如
Domain
和Path
)决定何时将它们发送给服务器。 -
服务器端的后端数据库 服务器通常会将 Cookie 中的某些信息(如用户 ID)与后端数据库中的记录关联起来。例如,当用户登录时,服务器会生成一个唯一的用户 ID,并将其存储在 Cookie 中,同时在数据库中记录该用户的登录状态和其他相关信息。
Cookies 的工作原理
-
首次访问
- 用户首次访问电商网站时,服务器会为用户生成一个唯一的 ID(如
1678
),并在 HTTP 响应中通过Set-Cookie
头将该 ID 发送给用户:
1
Set-Cookie: user_id=1678; Path=/; Domain=example.com
- 同时,服务器会在后端数据库中为该用户创建一个记录,存储用户的基本信息(如购物车内容、浏览历史等)。
- 用户首次访问电商网站时,服务器会为用户生成一个唯一的 ID(如
-
后续访问
- 当用户再次访问该网站时,浏览器会自动将之前收到的 Cookie 通过
Cookie
头发送给服务器:
1
Cookie: user_id=1678
- 服务器通过解析
user_id
,从数据库中找到与该用户相关的记录,从而恢复用户的会话状态,例如显示用户的购物车内容或推荐商品。
- 当用户再次访问该网站时,浏览器会自动将之前收到的 Cookie 通过
-
跨网站跟踪(Third-Party Cookies)
- 有些网站可能会使用第三方 Cookie 来跟踪用户在多个网站上的行为。例如,广告公司可能会在多个网站上设置相同的 Cookie,从而跟踪用户的浏览历史,并根据这些信息推送个性化广告。
不使用Cookies如何保持状态
除了使用 Cookies,还有其他方法可以在客户端和服务器之间保持状态: - 在协议端点保持状态(Maintain State at Protocol Endpoints):服务器可以在本地存储用户的会话信息,并通过其他机制(如 URL 参数或隐藏表单字段)在请求中传递这些信息。 - 使用令牌(Tokens):例如,OAuth 令牌可以用于在客户端和服务器之间传递用户身份信息,而不需要使用传统的 Cookie
Web caches (Proxy server)
Web 缓存(Web Caching)的定义
Web 缓存是一种存储机制,用于在客户端和服务器之间缓存(存储)常用的 Web 对象(如 HTML 页面、图片、CSS 文件等)。通过缓存这些对象,可以减少对原始服务器(origin server)的请求,从而提高响应速度并降低网络流量。

Web 缓存的工作原理
Web 缓存通常由 代理服务器(Proxy Server) 实现。以下是 Web 缓存的基本工作流程:
- 用户配置浏览器:
- 用户将浏览器配置为指向一个 Web 缓存服务器。这个缓存服务器也被称为代理服务器。
- 浏览器将所有 HTTP 请求发送到这个缓存服务器,而不是直接发送到原始服务器。
- 缓存服务器处理请求:
- 当缓存服务器收到浏览器的请求时,它会检查请求的资源是否已经存储在本地缓存中。
- 如果资源在缓存中(Cache Hit):
- 缓存服务器直接将缓存的对象返回给客户端,而无需再次请求原始服务器。
- 如果资源不在缓存中(Cache Miss):
- 缓存服务器会向原始服务器发送请求,获取所需的资源。
- 原始服务器返回资源后,缓存服务器将资源存储在本地缓存中,并同时将资源返回给客户端。
- 缓存的有效性:
- 原始服务器会在 HTTP 响应头中告诉缓存服务器该对象的缓存策略(例如,是否可以缓存、缓存的有效期等)。
- 常见的缓存控制头包括:
Cache-Control
:指定缓存策略,如max-age
表示缓存的有效期。Expires
:指定缓存的过期时间。ETag
:用于验证缓存对象是否是最新的。
Electronic mail
电子邮件系统主要由以下三大组件构成:
- 用户代理(User Agents):也称为“邮件阅读器”,用于撰写、编辑和阅读邮件,例如Outlook、Thunderbird或iPhone邮件客户端。用户代理将发送的邮件存储在邮件服务器上。
- 邮件服务器(Mail Servers):负责存储用户的收件箱(包含收到的邮件)和发送邮件的消息队列。邮件服务器之间通过SMTP协议发送电子邮件。
- SMTP(简单邮件传输协议):用于邮件服务器之间发送电子邮件的协议,使用TCP端口25进行可靠传输。
邮件发送流程
以Alice向Bob发送邮件为例:
- Alice使用用户代理撰写邮件,收件人是(bob@someschool.edu)。
- Alice的用户代理将邮件发送到她的邮件服务器,邮件被放入消息队列。
- Alice的邮件服务器(作为SMTP客户端)通过TCP连接与Bob的邮件服务器(作为SMTP服务器)建立连接。
- SMTP客户端将Alice的邮件通过TCP连接发送给Bob的邮件服务器。
- Bob的邮件服务器将邮件放入Bob的收件箱。
- Bob使用用户代理读取邮件。
SMTP协议
- 传输方式:使用TCP可靠传输,端口为25。
- 传输过程:分为三个阶段:
- SMTP握手(Handshaking):通过HELO命令进行问候。
- 消息传输:通过MAIL FROM、RCPT TO和DATA命令发送邮件。
- 关闭连接:使用QUIT命令结束会话。
- 交互方式:命令和响应均为ASCII文本,响应包含状态码和描述信息。
- 特点:
- 使用持久连接。
- 邮件内容(包括头部和正文)必须为7位ASCII码。
- 使用CRLF.CRLF作为消息结束标志。
- 与HTTP的比较:
- HTTP是“拉取”模式,SMTP是“推送”模式。
- 两者都使用ASCII命令/响应交互和状态码。
- HTTP每个对象封装在单独的响应消息中,SMTP则通过多部分消息发送多个对象。

邮件消息格式
- 协议:SMTP用于邮件交换,RFC 822定义了文本消息格式。
- 格式:
- 头部:包含To、From、Subject等字段。
- 正文:邮件内容,仅限ASCII字符。
- 分隔:头部和正文之间通过空行分隔。


DNS (Domain Name System)
DNS的背景和作用
- 背景:互联网中的主机和路由器需要使用IP地址来寻址数据报,但IP地址是32位数字,难以记忆,而人类更习惯使用域名(如www.yahoo.com)来访问网站。因此,需要一种机制来实现IP地址和域名之间的映射。
- 作用:DNS是一个分布式数据库,实现了域名和IP地址之间的双向映射,是互联网核心功能之一,作为应用层协议,通过主机和域名服务器之间的通信来解析名称。




- 本地域名服务器:不属于DNS层次结构的严格组成部分,每个ISP(如家庭ISP、公司、大学等)都有一个本地DNS服务器,也称为默认域名服务器。当主机发起DNS查询时,本地DNS服务器会首先响应,如果本地缓存中有最近的名称到地址映射对,则直接返回结果;如果没有,则作为代理将查询转发到DNS层次结构中。

DNS的查询过程
- 迭代查询:客户端向本地DNS服务器发起查询,本地DNS服务器如果无法解析,则向更高层次的DNS服务器(如根服务器)查询,根服务器返回相应的TLD服务器信息,本地DNS服务器再向TLD服务器查询,TLD服务器返回权威DNS服务器信息,本地DNS服务器最后向权威DNS服务器查询并获取最终结果,然后返回给客户端。


DNS的缓存机制
- 缓存原理:任何DNS服务器在解析出一个域名到IP地址的映射后,会将该映射信息缓存起来。缓存条目会在一定时间(TTL,生存时间)后失效并消失。
- 缓存优势:TLD服务器通常会被缓存在本地DNS服务器中,因此根DNS服务器不会被频繁访问,减少了根服务器的负载。
- 缓存问题:缓存的条目可能会过时,如果主机的IP地址发生变化,可能需要等到所有TTL过期后,互联网上的DNS服务器才会更新到新的IP地址,导致在TTL过期前,部分用户可能无法访问到正确的目标地址。
DNS记录类型
DNS是一个分布式数据库,存储着各种资源记录(RR),常见的记录类型包括:
- NS记录:名称是域名(如foo.com),值是该域名的权威DNS服务器的主机名。
- A记录:名称是主机名,值是对应的IP地址。
- CNAME记录:名称是别名,值是规范名称(真实名称),例如www.ibm.com可能是一个CNAME记录,指向servereast.backup2.ibm.com。
- MX记录:值是与名称关联的邮件服务器的名称。


DNS记录的插入过程
以新公司“Network Utopia”为例,其注册域名networkuptopia.com时,需要在DNS注册商(如Network Solutions)处注册域名,并提供权威DNS服务器的名称和IP地址。注册商会在.com顶级域名服务器中插入两条资源记录,一条是NS记录,将networkuptopia.com指向其权威DNS服务器dns1.networkuptopia.com;另一条是A记录,将dns1.networkuptopia.com的IP地址设置为212.212.212.1。然后,该公司的权威DNS服务器会创建www.networkuptopia.com的A记录和networkuptopia.com的MX记录等。
DNS不采用集中式的原因
- 单点故障:如果采用集中式DNS,一旦中心服务器出现故障,整个互联网的DNS解析将无法进行,导致互联网瘫痪。
- 流量压力:互联网的DNS查询量非常大,集中式服务器难以承受如此巨大的流量。
- 延迟问题:集中式服务器距离用户可能较远,导致查询延迟较高,影响用户体验。
- 维护困难:集中式服务器的维护成本和复杂度较高,难以应对互联网的快速变化和大规模扩展需求。