网络应用是计算机网络存在的理由,一批早起的网络应用主要有电子邮件、远程访问、文件传输等,但是随着计算机网络的发展和人类无穷无尽的需求,越来越多的网络应用被开发出来,例如即时通讯和对等(P2P)文件共享,IP 电话、视频会议等。
研发网络应用程序的核心是写出能够运行在不同的端系统和通过网络彼此通信的程序。例如,在网络应用程序中,有两个互相通信的不同程序:一个是运行在用户主机上的浏览器程序;另一个是运行在 Web 服务器主机上的 Web 服务器程序。
进程通信
两种体系结构,一种是客户-服务器模式,一种是P2P 对等模式。我们都知道一个计算机允许同时运行多个应用程序,在我们看起来这些应用程序好像是同时运行的,那么它们之间是如何通信的呢?
用操作系统的术语来说,进行通信实际上是 进程(process)而不是程序。一个进程可以被认为是运行在端系统中的程序。当多个进程运行在相同的端系统上,它们使用进程间的通信机制相互通信。
进程与计算机网络之间的接口
计算机是庞大且繁杂的,计算机网络也是,应用程序不可能只有一个进程组成,它同样是多个进程共同作用协商运行,然而,分布在多个端系统之间的进程是如何进行通信的呢?实际上,每个进程之间会有一个 套接字(socket) 的软件接口存在,套接字是应用程序的内部接口,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将 I/O 插入到网络中,并与网络中的其他应用程序进行通信。
Socket 属于主机或者服务进程的内部接口,由应用程序开发人员进行控制,两台端系统之间进行通信会通过 TCP 的缓冲区经由网络传输到另一个端系统的 TCP 缓冲区,Socket 从 TCP 缓冲区读取报文供应用程序内部使用。
套接字是建立网络应用程序的可编程接口,因此套接字也被称为应用程序和网络之间的 应用程序编程接口(Application Programming Interface,API)。应用程序开发人员可以控制套接字内部细节,但是无法控制运输层的传输,只能对运输层的传输协议进行选择,还可以对运输层的传输参数进行选择,比如最大缓存和最大报文长度等。
应用层概述
- 每个应用层协议都是为了解决某一类应用问题,而问题的解决又往往是通过位于不同主机中的多个应用进程之间的通信和协同工作来完成的。应用层的具体内容就是规定应用进程在通信时所遵循的协议。
- 应用层的许多协议都是基于客户服务器方式。客户(client)和服务器(server)都是指通信中所涉及的两个应用进程。客户服务器方式所描述的是进程之间服务和被服务的关系。客户是服务请求方,服务器是服务提供方。
应用层协议(application-layer protocol) 定义了运行在不同端系统上的应用进程如何相互传递报文。
应用层协议会定义:
- 交换的报文类型,如请求报文和响应报文;
- 各种报文类型的语法,如报文中的各个字段公共详细描述;
- 字段的语义,即包含在字段中信息的含义;
- 进程何时、如何发送报文及对报文进行响应。
应用层协议分类:
- 域名系统(Domain Name System, DNS):用于实现网络设备名字到 IP 地址映射的网络服务。
- 文件传输协议(File Transfer Protocol,FTP):用于实现交互式文件传输功能。
- 邮件传送协议(Simple Mail Transfer Protocol, SMTP):用于实现电子邮箱传送功能。
- 超文本传输协议(HyperText Transfer Protocol,HTTP):用于实现 Web 服务。
- 远程登录协议(Telnet):用于实现远程登录功能。
DNS工作概述
假设运行在用户主机上的某些应用程序(如 Web 浏览器或邮件阅读器) 需要将主机名转换为 IP 地址。这些应用程序将调用 DNS 的客户端,并指明需要被转换的主机名。用户主机上的 DNS 收到后,会使用 UDP 通过 53 端口向网络上发送一个 DNS 查询报文,经过一段时间后,用户主机上的 DNS 会收到一个主机名对应的 DNS 回答报文。因此,从用户主机的角度来看,DNS 就像是一个黑盒子,其内部的操作你无法看到。但是实际上,实现 DNS 这个服务的黑盒子非常复杂,它由分布于全球的大量 DNS 服务器以及定义了 DNS 服务器与查询主机通信方式的应用层协议组成。
- 域名解析过程:
本地域名服务器向根域名服务器的查询通常是采用迭代查询。当根域名服务器收到本地域名服务器的迭代查询请求报文时,要么给出所要查询的 IP 地址,要么告诉本地域名服务器:“你下一步应当向哪一个域名服务器进行查询”。然后让本地域名服务器进行后续的查询。
- DNS 缓存:
DNS 缓存(DNS caching) 有时也叫做 DNS 解析器缓存,它是由操作系统维护的临时数据库,它包含有最近的网站和其他 Internet 域的访问记录。也就是说, DNS 缓存只是计算机为了满足快速的响应速度而把已加载过的资源缓存起来,再次访问时可以直接快速引用的一项技术和手段。
在浏览器向外部发出请求之前,计算机会拦截每个请求并在 DNS 缓存数据库中查找域名,该数据库包含有最近的域名列表,以及 DNS 首次发出请求时 DNS 为它们计算的地址。
- DNS记录
共同实现 DNS 分布式数据库的所有 DNS 服务器存储了资源记录(Resource Record, RR),RR 提供了主机名到 IP 地址的映射。每个 DNS 回答报文中会包含一条或多条资源记录。RR 记录用于回复客户端查询。
资源记录是一个包含了下列字段的 4 元组:(Name, Value, Type, TTL)
RR 会有不同的类型,下面是不同类型的 RR 汇总表
| DNS RR 类型解释 | |
|---|---|
| A | 记录IPv4 主机记录,用于将域名映射到 IPv4 地址 |
| AAAA | 记录IPv6 主机记录,用于将域名映射到 IPv6 地址 |
| CNAME | 记录别名记录,用于映射 DNS 域名的别名 |
| MX | 记录邮件交换器,用于将 DNS 域名映射到邮件服务器 |
| PTR | 记录指针,用于反向查找(IP地址到域名解析) |
| SRV | 记录SRV记录,用于映射可用服务 |
FTP概述
- 文件传送协议 FTP (File Transfer Protocol) 是因特网上使用得最广泛的文件传送协议
- FTP 提供交互式的访问,允许客户指明文件的类型与格式,并允许文件具有存取权限
- FTP 屏蔽了各计算机系统的细节,因而适合于在异构网络中任意计算机之间传送文件
- FTP 使用客户服务器方式。一个 FTP 服务器进程可同时为多个客户进程提供服务。FTP 的服务器进程由两大部分组成:一个主进程,负责接受新的请求;另外有若干个从属进程,负责处理单个请求
主进程的工作步骤
- 打开熟知端口(端口号为 21),使客户进程能够连接上。
- 等待客户进程发出连接请求。
- 启动从属进程来处理客户进程发来的请求。从属进程对客户进程的请求处理完毕后即终止,但从属进程在运行期间根据需要还可能创建其他一些子进程。
- 回到等待状态,继续接受其他客户进程发来的请求。主进程与从属进程的处理是并发地进行
两个连接
- 控制连接在整个会话期间一直保持打开,FTP 客户发出的传送请求通过控制连接发送给服务器端的控制进程,但控制连接不用来传送文件。
- 实际用于传输文件的是数据连接。服务器端的控制进程在接收到 FTP 客户发送来的文件传输请求后就创建"数据传送进程"和"数据连接",用来连接客户端和服务器端的数据传送进程。
- 数据传送进程实际完成文件的传送,在传送完毕后关闭"数据传送连接"并结束运行。

数据连接的建立类型:
- 主动模式:服务端从20端口主动向客户端发起连接——ftp客户端告诉FTP服务器使用什么端口监听,FTP服务器和FTP客户端的这个端口建立连接,源端口20
- 被动模式:服务端在指定范围内的某个端口被动等待客户端发起连接——FTP服务器打开一个新端口,等待FTP客户端的连接
因特网中的电子邮件
电子邮件系统有三个主要组成部分:用户代理(user agent)、邮件服务器(mail server)、和简单邮件传输协议(Simple Mail Transfer Protocol,SMTP)。下面我们就来描述一下邮件收发的过程。
用户代理允许用户阅读、回复、转发、保存和撰写报文。微软的 Outlook 和 Apple Mail 是电子邮件用户代理的例子。当用户编写完邮件时,他的用户代理向邮件服务器发送邮件,此时用户发送的邮件会放在邮件服务器的外出消息队列(Outgoing message queue)中,当接收方用户想要阅读邮件时,他的用户代理直接从外出消息队列中去取得该报文。
邮件服务器构成了整个邮件系统的核心。每个接收方在其中的邮件服务器上会有一个邮箱(mailbox) 存在。用户的邮箱管理和维护发送给他的报文。一个典型的邮件发送过程是:从发送方的用户代理开始,传输到发送方的邮件服务器,再传输到接收方的邮件服务器,然后在这里被分发到接收方的邮箱中。用接收方的用户想要从邮箱中读取邮件时,他的邮件服务器会对用户进行认证。如果发送方发送的邮件无法正确交付给接收方的服务器,那么发送方的用户代理会把邮件存储在一个报文队列(message queue)中,并在以后尝试再次发送,通常每30分钟发送一次,如果一段时间后还发送不成功,服务器就会删除报文队列中的邮件并以电子邮件的方式通知发送方。
SMTP 是因特网电子邮件中的主要的应用层协议。SMTP 使用 TCP 作为运输层协议,保证数据传输的可靠性。
SMTP 协议传输过程
- 建立连接:在这一阶段,SMTP 客户请求与服务器的25端口建立一个 TCP 连接。一旦连接建立,SMTP 服务器和客户就开始相互通告自己的域名,同时确认对方的域名。
- 邮件传送:一旦连接建立后,就开始邮件传输。SMTP 依靠 TCP 能够将邮件准确无误地传输到接收方的邮件服务器中。SMTP 客户将邮件的源地址、目的地址和邮件的具体内容传递给 SMTP 服务器,SMTP 服务器进行相应的响应并接收邮件。
- 连接释放:SMTP 客户发出退出命令,服务器在处理命令后进行响应,随后关闭 TCP 连接。
SMTP 一般不使用中间邮件服务器发送邮件,即使这两个邮件服务器位于地球的两端也是这样的,TCP 连接通常直接连接端到端的服务器。
SMTP协议状态码
- 220:服务就绪
- 250:请求动作正确完成(HELO、MAIL FROM、RCPT TO、QUIT指令执行成功会返回此信息)
- 235:认证通过
- 221:正在处理
- 354:开始发送邮件内容,提示以特殊行.结束邮件内容
- 500:语法错误,命令不能识别
- 552:中断处理
下面我们分析一个实际的 SMTP 邮件发送过程,以下统称为SMTP客户(C)和 SMTP服务器(S)。客户的主机名为 crepes.fr,服务器的主机名为 hamburger.edu。以 C: 开头的 ASCII 码文本就是客户交给 TCP 套接字的那些行,以 S: 开头的 ASCII 码则是服务器发送给其 TCP 套接字的那些行。一旦创建了连接,就开始了如下过程:
1 | S: 220 hamburger.edu |
在上述例子中,客户从邮件服务器 crepes.fr 向邮件服务器 hamburger.edu 发送了一个报文 (" Do you like ketchup? How about pickles? ") 。作为对话的一部分,该客户发送了 5 条命令: HELO(是 HELLO 的缩写)、 MAMIL FROM、RCPT TO、DATA 以及 QUIT。这些命令都是自解释的。
上面是一个简单的 SMTP 交换过程,包括了连接建立、邮件传送和连接释放三个具体过程.
首先建立 TCP 连接、SMTP 调用 TCP 协议的25号端口监听连接请求,然后客户端发送 HELO 指令用来表明自己是发送方的身份,然后服务端作出响应。然后,客户端发送 MAIL FROM 命令,表明客户端的邮件地址是 alice@crepes.fr ,服务器以 OK 作为响应,表明准备接收。客户端发送 RCPT TO 表明接收方的电子邮件地址,可以有多个 RCPT 行,即一份邮件可以同时发送给多个收件人。服务器端则表示是否愿意为收件人接收邮件。协商结束后,客户端用 DATA 命令发送信息,结束标志是CRLF.CRLF ,也就是 回车换行.回车换行。最后,控制交互的任一端可选择终止会话,为此它发出一个 QUIT 命令,另一端用命令221响应,表示同意终止连接,双方将关闭连接。
SMTP 的报文会有局限性,SMTP 的局限性表现在只能发送 ASCII 码格式的报文,不支持中文、法文、德文等,它也不支持语音、视频的数据。通过 MIME协议,对 SMTP 补充。MIME 使用网络虚拟终端(NVT)标准,允许非ASCII码数据通过SMTP传输。
Web 和 HTTP
Web(World Wide Web)即全球广域网,也就是 URL 为 www 开头的网络,它是 HTTP 协议的主要载体,是建立在 Internet 上的一种网络服务,我们一般讲的 W超文本传输协议可以进行文字分割:超文本(Hypertext)、传输(Transfer)、协议(Protocol),按照范围的大小"协议 > 传输 > 超文本"。下面就分别对这三个名次做一个解释。
- 超文本
在互联网早期的时候,我们输入的信息只能保存在本地,无法和其他电脑进行交互。我们保存的信息通常都以文本即简单字符的形式存在,文本是一种能够被计算机解析的有意义的二进制数据包。而随着互联网的高速发展,两台电脑之间能够进行数据的传输后,人们不满足只能在两台电脑之间传输文字,还想要传输图片、音频、视频,甚至点击文字或图片能够进行超链接的跳转,那么文本的语义就被扩大了,这种语义扩大后的文本就被称为超文本(Hypertext)。
- 传输
两台计算机之间会形成互联关系进行通信,我们存储的超文本会被解析成为二进制数据包,由传输载体(例如同轴电缆,电话线,光缆)负责把二进制数据包由计算机终端传输到另一个终端的过程。
- 协议
协议,网络协议的简称,网络协议是通信计算机双方必须共同遵从的一组约定。如怎么样建立连接、怎么样互相识别等。只有遵守这个约定,计算机之间才能相互通信交流。它的三要素是:语法、语义、时序。
为了使数据在网络上从源到达目的,网络通信的参与方必须遵循相同的规则,这套规则称为协议(protocol),它最终体现为在网络上传输的数据包的格式。
- HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范的一个协议。
非持久性连接
假设访问的 URL 地址为 www. someSchool.edu /someDepartment/home.index 当我们输入网址并点击回车时,浏览器内部会进行如下操作:
- DNS 服务器会首先进行域名的映射,找到访问www .someSchool.edu 所在的地址,然后 HTTP 客户端进程在 80 端口发起一个到服务器 www .someSchool.edu 的 TCP 连接(80 端口是 HTTP 的默认端口)。在客户和服务器进程中都会有一个套接字与其相连。
- HTTP 客户端通过它的套接字向服务器发送一个 HTTP 请求报文。该报文中包含了路径 someDepartment/home.index 的资源。
- HTTP 服务器通过它的套接字接受该报文,进行请求的解析工作,并从其存储器(RAM 或磁盘)中检索出对象 www. someSchool.edu/ someDepartment/home.index,然后把检索出来的对象进行封装,封装到 HTTP 响应报文中,并通过套接字向客户进行发送。
- HTTP 服务器随即通知 TCP 断开 TCP 连接,实际上是需要等到客户接受完响应报文后才会断开 TCP 连接。
- HTTP 客户端接受完响应报文后,TCP 连接会关闭。HTTP 客户端从响应中提取出报文中是一个 HTML 响应文件,并检查该 HTML 文件,然后循环检查报文中其他内部对象。
- 检查完成后,HTTP 客户端会把对应的资源通过显示器呈现给用户。
至此,键入网址再按下回车的全过程就结束了。上述过程描述的是一种简单的请求-响应全过程,真实的请求-响应情况可能要比上面描述的过程复杂很多。
上面的步骤举例说明了非持久性连接的使用,其中每个 TCP 链接都在服务器发送完成后关闭。每个 TCP 连接只传输一个请求报文和响应报文。
持久性连接的 HTTP
非持久性连接有一些缺点。第一,必须为每个请求的对象建立和维护一个全新的连接。对于每个这样的连接来说,在客户端和服务器中都要分配 TCP 的缓冲区和保持 TCP 变量,这给 Web 服务器带来了严重的负担。因为一台 Web 服务器可能要同时服务于数百甚至上千个客户请求。
在采用 HTTP 1.1 持续连接的情况下,服务器在发送响应后保持该 TCP 连接打开不关闭。在相同的客户与服务器之间,后续的请求和响应报文能够通过相同的连接进行传送。一般来说,如果一跳连接经过一定的时间间隔(可配置)后仍未使用,HTTP 服务器就应该关闭其连接。
HTTP 报文格式
HTTP 协议主要由三大部分组成:
- 起始行(start line):描述请求或响应的基本信息;
- 头部字段(header):使用 key-value 形式更详细地说明报文;
- 消息正文(entity):实际传输的数据,它不一定是纯文本,可以是图片、视频等二进制数据。
其中起始行和头部字段并成为 请求头 或者 响应头,统称为 Header;消息正文也叫做实体,称为 body。HTTP 协议规定每次发送的报文必须要有 Header,但是可以没有 body,也就是说头信息是必须的,实体信息可以没有。而且在 header 和 body 之间必须要有一个空行(CRLF)。

HTTP 请求报文
我们使用上面的那个例子来看一下 http 的请求报文

报文是用普通 ASCII 文本书写的,这样保证人能够可以看懂。然后,我们可以看到每一行和下一行之间都会有换行,而且最后一行(请求头部后)再加上一个回车换行符。
每个报文的起始行都是由三个字段组成:方法、URL 字段和 HTTP 版本字段。


- 头部:
1 | Client-IP:提供了运行客户端的机器的IP地址 |
- HTTP 请求方法
HTTP 请求方法一般分为 8 种,它们分别是:
- GET 获取资源,GET 方法用来请求访问已被 URI 识别的资源。指定的资源经服务器端解析后返回响应内容。也就是说,如果请求的资源是文本,那就保持原样返回
- POST 传输实体,虽然 GET 方法也可以传输主体信息,但是便于区分,我们一般不用 GET 传输实体信息,反而使用 POST 传输实体信息
- PUT 传输文件,PUT 方法用来传输文件。就像 FTP 协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求 URI 指定的位置。但是,鉴于 HTTP 的 PUT 方法自身不带验证机制,任何人都可以上传文件 , 存在安全性问题,因此一般的 W eb 网站不使用该方法。
- HEAD 获得响应首部,HEAD 方法和 GET 方法一样,只是不返回报文主体部分。用于确认 URI 的有效性及资源更新的日期时间等。
- DELETE 删除文件,DELETE 方法用来删除文件,是与 PUT 相反的方法。DELETE 方法按请求 URI 删除指定的资源。
- TRACE 追踪路径,TRACE 方法是让 Web 服务器端将之前的请求通信环回给客户端的方法。
- CONNECT 要求用隧道协议连接代理,CONNECT 方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。主要使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加 密后经网络隧道传输。
- OPTIONS 询问支持的方法,OPTIONS 方法用来查询针对请求 URI 指定的资源支持的方法。
GET和POST之间的区别:
- GET方法的数据参数是暴露在起始行的URL中的,而POST方法的数据参数是在报文主体中的
- GET方法相对来说没有POST安全,因为它的数据参数可以直接从URL中获取,但是GET的效率更高
- GET方法的数据参数大小有一定的限制(1024)(原因也是因为它的数据参数是放在URL中的),而POST对数据大小是没有限制的。
- 本质区别是GET是从服务器上请求数据,而POST是向服务器发送数据
HTTP 应答报文

应答报文的起始行也包含了3个部分
- 协议类型及版本号
- 状态码
- 状态码的文字描述
状态码:
在http协议中,状态码被分为了5大类
- 100~199(信息性状态码)
- 200~299(成功状态码)
- 300~399(重定向状态码)
- 400~499(客户端错误状态码)
- 500~599(服务器端错误状态码)
- 头部:
1 | Age:(从最初创建开始)响应持续时间 |
HTTP 请求 URL
我们再通过一个完整的域名解析一下 URL
1 | http:// |
- 首先出场的是 http
http: //告诉浏览器使用何种协议。对于大部分 Web 资源,通常使用 HTTP 协议或其安全版本,HTTPS 协议。另外,浏览器也知道如何处理其他协议。例如, mailto: 协议指示浏览器打开邮件客户端;ftp:协议指示浏览器处理文件传输。
- 第二个出场的是 主机
www. example.com 既是一个域名,也代表管理该域名的机构。它指示了需要向网络上的哪一台主机发起请求。当然,也可以直接向主机的 IP address 地址发起请求。但直接使用 IP 地址的场景并不常见。
- 第三个出场的是 端口
我们前面说到,两个主机之间要发起 TCP 连接需要两个条件,主机 + 端口。它表示用于访问 Web 服务器上资源的入口。如果访问的该 Web 服务器使用HTTP协议的标准端口(HTTP为80,HTTPS为443)授予对其资源的访问权限,则通常省略此部分。否则端口就是 URI 必须的部分。
- 第四个出场的是 路径
/path/to/myfile.html 是 Web 服务器上资源的路径。以端口后面的第一个 / 开始,到 ? 号之前结束,中间的 每一个/ 都代表了层级(上下级)关系。这个 URL 的请求资源是一个 html 页面。
- 后面的是 查询参数
?key1=value1&key2=value2 是提供给 Web 服务器的额外参数。如果是 GET 请求,一般带有请求 URL 参数,如果是 POST 请求,则不会在路径后面直接加参数。这些参数是用 & 符号分隔的键/值对列表。key1 = value1 是第一对,key2 = value2 是第二对参数
- 紧跟着参数的是锚点
#SomewhereInTheDocument 是资源本身的某一部分的一个锚点。锚点代表资源内的一种“书签”,它给予浏览器显示位于该“加书签”点的内容的指示。 例如,在HTML文档上,浏览器将滚动到定义锚点的那个点上;在视频或音频文档上,浏览器将转到锚点代表的那个时间。值得注意的是 # 号后面的部分,也称为片段标识符,永远不会与请求一起发送到服务器。
P2P 文件分发
我们上面探讨的协议 HTTP、SMTP、DNS 都采用了客户-服务器 模式,这种模式会极大依赖总是打开的基础设施服务器。而 P2P是客户端与客户端模式,对总是打开的基础设施服务器有最小的依赖。
P2P 的全称是 Peer-to-peer, P2P ,是一种分布式体系结构的计算机网络。在 P2P 体系中,所有的计算机和设备都被称为对等体,他们互相交换工作。对等网络中的每个对等方都等于其他对等方。网络中没有特权对等体,也没有主管理员设备。
从某种意义上说,对等网络是计算机世界中最平等的网络。每个对等方都相等,并且每个对等方具有与其他对等方相同的权利和义务。对等体同时是客户端和服务器。
实际上,对等网络中可用的每个资源都是在对等之间共享的,而无需任何中央服务器。P2P 网络中的共享资源可以是诸如处理器使用率,磁盘存储容量或网络带宽等。
P2P 用来做什么
P2P 的主要目标是共享资源并帮助计算机和设备协同工作,提供特定服务或执行特定任务。如前面说到的,P2P 用于共享各种计算资源,例如网络带宽或磁盘存储空间。 但是,对等网络最常见的例子是 Internet 上的文件共享。 对等网络非常适合文件共享,因为它们允许连接到它们计算机等同时接收文件和发送文件。
BitTorrent协议 是 P2P 使用的主要协议。
P2P 网络的作用
P2P 网络具有一些使它们有用的特征
- 很难完全掉线,即使其中的一个对等方掉线,其他对等方仍在运行并进行通信。 为了使 P2P(对等)网络停止工作,你必须关闭所有对等网络。对等网络具有很强的可扩展性。 添加新的对等节点很容易,因为你无需在中央服务器上进行任何中央配置。
- 当涉及到文件共享时,对等网络越大,速度越快。 在 P2P 网络中的许多对等点上存储相同的文件意味着当某人需要下载文件时,该文件会同时从多个位置下载。