应用层协议原理
应用层协议只能在应用层工作,这种限制提高了开发效率
:::tip 🔔
网络核心没用应用层功能
网络应用只在端系统上存在,快速网络应用开发和部署
:::
应用层程序的体系结构
客户-服务器结构 (C/S)
:::tip 🔔 特点
服务器:
一直运行
IP固定
在数据中心,但是拓展性差【?】
客户端:
主动联系服务器
可以间歇性联网
可以是动态IP
不直接与其他客户端通信(经过服务器)
:::
对等体系结构 (P2P)
:::tip 🔔 特点
对位于数据中心的专用服务器有最小的(或者没有)依赖。
没有一直运行的服务器
任意端系统之间可以直接通信
每一个节点既是客户端也是服务器
因此有较强的拓展性(Self-scalability)
参与的主机可以间歇性连接且可以改变IP地址
例如:迅雷
:::
进程通信
进程是在主机上运行的程序
:::tip 🔔 进程通信的特点
在同一个主机上,使用进程通信机制进行通信(操作系统定义的)
在不同主机上使用报文(message)通信(借助传输层)
:::
客户端进程:发起通信的进程
服务器进程:等待连接的进程
注意: 在P2P文件共享中,当对等方A请求对等方B送一个特定的文件时,在这个特定的通信会话中对等方A是客户,而对等方B是服务器。(P2P架构的应用也有客户端和服务器进程之分)
:::caution ⚠ 进程寻址
在两个主机之间通信时,需要定义两种数据信息:一种是主机的地址,二是主机中指定接收进程的标识符。在Internet中,主机由IP地址进行标识,接收进程由端口号(Port Number)进行标识。例如,Web服务器使用端口号80,邮件服务器(SMTP)使用端口号25.
:::
传输层为应用层提供的服务
数据丢失率:传输可靠的文件。
吞吐:完成进程交付比特的速率。
延迟:传输层提供的服务的延迟。
安全性:保证机密性和完整性。
常见的应用
应用 | 数据丢失 | 带宽 | 时间敏感 | 应用层协议 | 支撑的传输层协议 |
---|---|---|---|---|---|
文件传输 | 不能丢失 | 弹性 | 不 | FTP* | TCP |
电子邮件 | 不能丢失 | 弹性 | 不 | SMTP | TCP |
Web文档 | 不能丢失 | 弹性(几kbps) | 不 | HTTP | TCP |
因特网电话 | 容忍丢失 | 音频(几kbps~1Mbps) | 是,100ms | SIP、RTP | UDP或TCP |
视频会议 | 容忍丢失 | 视频(10kbps~5Mbps) | 是,100ms | SIP | UDP或TCP |
交互式游戏 | 容忍丢失 | 几kbps~10kbps | 是,100ms | \ | \ |
智能手机讯息 | 不能丢失 | 弹性 | 是或不是(看具体) | \ | \ |
应用层协议
应用层协议: 定义了运行在不同端系统上的应用程序进程如何相互交换报文,特别是应用层协议定义了:
交换的报文类型: 请求和应答报文
各种报文类型的语法: 报文中的各个字段及其描述
字段的 语义:即字段取值的含义
进程何时、如何发送报文及对报文进行响应的规则
TCP服务
可靠的传输服务
流量控制:发送方不会淹没接受方
拥塞控制:当网络出现拥塞时,能抑制发送方
不能提供的服务:时间保证、最小吞吐保证和安全
面向连接:要求在客户端进程和服务器进程之间建立连接
UDP服务
不可靠的数据传输
不提供服务:可靠,流量控制、拥塞控制、时间、带宽保证、建立连接
:::caution ⚠ UDP为什么存在
能够区分不同的进程,而IP服务不能.在IP提供的主机到主机端到端功能的基础上,区分了主机的应用进程.无需建立连接,省去了建立连接时间,适合事务性的应用。不做可靠性的工作,例如检错重发,适合那些对实时性要求比较高而正确性要求不高的应用。因为为了实现可靠性(准确性、保序等),必须付出时间代价 没有拥塞控制和流量控制,能够按照设定的速度发送数据.而在TCP上面的应用,应用发送数据的速度和主机向网络发送的实际速度是不一致的,因为有流量控制和拥塞控制。
因此,使用UDP服务可以减少大量不必要的时间开支。现在,UDP服务正有取代TCP的趋势。 :::
HTTP:超文本传输协议
在客户/服务器模式中:
客户:请求、接收和显示Web对象的流量器
服务器:对请求进行响应,发送对象的Web请求
:::tip 🔔 HTTP采用TCP服务
客户发起一个与服务器的TCP连接(建立套接字), 端口号为80
服务器接受客户的TCP连接
在浏览器(HTTP客户端)与Web服务器(HTTP服务器server)交换HTTP报文(应用层协议报文)
TCP连接关闭
HTTP是无状态的
服务器并不维护关于客户的任何信息
:::
:::caution ⚠ 什么是无状态协议
常见的许多七层协议实际上是有状态的,例如SMTP协议,它的第一条消息必须是HELO,用来握手,在HELO发送之前其他任何命令都是不能发送的;接下来一般要进行AUTH阶段,用来验证用户名和密码;接下来可以发送邮件数据;最后,通过QUT命令退出。可以看到,在整个传输层上,通信的双方是必须要时刻记住当前连接的状态的,因为不同的状态下能接受的命令是不同的;另外,之前的命令传输的某些数据也必须要记住,可能会对后面的命令产生影响。这种就叫做有状态的协议。
相反,为什么说HTTP是无状态的协议呢?因为它的每个请求都是完全独立的,每个请求包含了处理这个请求所需的完整的数据,发送请求不涉及到状态变更. :::
非持久HTTP连接
每个相应对是经一个单独的TCP连接发送,最多只有一个对象在TCP连接上发送,下载多个对象需要多个TCP连接
HTTP/1.0使用非持久连接
上图是一个HTTP/1.0的非持久连接,客户端向服务端请求一个对象(someDepartment/home.index),封装成请求报文传给客户端,客户端收到后,检索需要的对象,并将其封装成响应报文,并返回客户端。即刻Http关闭TCP连接。客户端检查收到的响应报文后找到n处应用对象,再次发起TCP连接进行请求。
持久HTTP连接
所有请求及响应经相同的TCP连接发送
多个对象可以在一个(在客户端和服务器之间的)TCP连接上传输
HTTP/1.1默认使用持久连接
:::tip 持久连接中的流水和非流水 非流水线方式: 客户在收到前一个响应后才能发出下 一个请求。这比非持续连接的两倍 RTT 的开销节省了 建立 TCP 连接所需的一个 RTT时间。但服务器在发 送完一个对象后,其 TCP 连接就处于空闲状态,浪费 了服务器资源。
流水线方式: 客户在收到 HTTP的响应报文之前就能够接着发送新的请求报文。一个接一个的请求报文到 达服务器后,服务器就可连续发回响应报文。使用流水线方式时,客户访问所有的对象只需花费一个 RTT 时间,使 TCP 连接中的空闲时间减少,提高了下载文档效率。
(详见后面的习题)
:::
响应时间模型
往返时间RTT(Round-Trip-Time):一个小的分组从客户端到服务器,在回到客户端的时间
响应时间:
一个RTT用来发起TCP连接=>一个RTT用来HTTP请求并等待HTTP响应=>文件传输时间
总共时间: 2RTT+传输时间
HTTP报文格式
请求报文
GET /somedir/page.html HTTP/1.1
Host: www.someschool.edu
User-agent: Mozila/4.0
Connection: close
Accept-language: fr
下图是wireshark捕获的HTTP报文:
响应报文
:::tip 🔔 Method请求方法
请求行由三部分组成:请求方法,请求URL(不包括域名),HTTP协议版本
请求方法比较多:GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT
GET:传递参数长度受限制,因为传递的参数是直接表示在地址栏中,而特定浏览器和服务器对url的长度是有限制的。因此,GET不适合用来传递私密数据,也不适合拿来传递大量数据。一般的HTTP请求大多都是GET。
在做web编程时,为了页面跳转携带数据,我们会将数据加在URL后面,比如:http://www.someschool.edu/somedir/page.html?name=jim&age=18 (opens in a new tab),问号后面就是数据部分。
POST:POST把传递的数据封装在HTTP请求数据中,以名称/值的形式出现,可以传输大量数据,对数据量没有限制,也不会显示在URL中。表单的提交用的是POST。
HEAD:HEAD跟GET相似,不过服务端接收到HEAD请求时只返回响应头,不发送响应内容。所以,如果只需要查看某个页面的状态时,用HEAD更高效,因为省去了传输页面内容的时间。用于页面状态的查询。
其他方法解析 (opens in a new tab)
:::
HTTP响应状态码
位于服务器->客户端的响应报文中的首行 一些状态码的例子:
200 OK
请求成功,请求对象包含在响应报文的后续部分
301 Moved Permanently
请求的对象已经被永久转移了;新的URL在响应报文的Location:首部行中指定
客户端软件自动用新的URL去获取对象
400 Bad Request
一个通用的差错代码,表示该请求不能被服务器解读
404 Not Found
请求的文档在该服务上没有找到
505 HTTP Version Not Supported
cookie
大多数主要的门户网站使用cookie
1.在HTTP响应报文中有一个cookie的首部行
2.在HTTP请求报文含有一个cookie的首部行
3.在用户端系统中保留有一个cookie文件,由用户的浏览器管理
4.在Web站点有一个后端数据库
:::tip 🔔 cookie的作用例子
Susan总是用同一个PC使用Internet Explore上网,她第一次访问了一个使用了Cookie的电子商务网站,当最初的HTTP请求到达服务器时,该Web站点产生一个唯一的ID,并以此作为索引在它的后端数据库中产生一个表项.
:::
WEB缓存 (代理服务器)
目标:不访问原始服务器,就满足客户的请求
用户设置浏览器: 通过缓存访问Web
浏览器将所有的HTTP请求发给缓存
在缓存中的对象:缓存直接返回对象
如对象不在缓存,缓存请求原始服务器,然后再将对象返回给客户端
实际上,缓存既是客户端也是服务器。
条件GET(The Conditional GET)
:::info 🌳 尽管高速缓存能减少响应时间,但是也引入了一个新的问题:缓存器中的对象副本可能是陈旧的。幸运的是,HTTP协议有一种机制,让缓存器证实它的对象是最新的。这种机制就是条件GET方法。
目标: 如果缓存器中的对象拷贝是最新的,就不要发送对象
缓存器: 在HTTP请求中指定缓存拷贝的日期 if-modified-since:
服务器: 如果缓存拷贝陈旧,则响应报文没包含对象:HTTP/1.0 304 Not Modified
:::
步骤
- 代理服务器代表请求浏览器发送一条请求报文给web server
GET /fruit/kiwi.gif HTTP/1.1
Host: www.exotiquecuisine.com
- Web 服务器将带有请求对象的响应报文发送给cache
HTTP/1.1 200 OK
Date: Sat, 8 Oct 2011 15:39:29
Server: Apache/1.3.0 (Unix)
Last-Modified: Wed, 7 Sep 2011 09:23:24
Content-Type: image/gif
(data data data ...)
cache将这个对象转发给请求的浏览器并且将这个对象缓存到自己的本地存储。重要的是,cache将这个对象上次修改的时间也存储了起来。
- 一周之后,另一个浏览器通过cache请求了相同的对象,并且这个对象仍然在cache里。由于这个对象可能在过去的一周里被修改过,cache就发起一个conditional GET来做一个更新检查。
具体的报文如下:
GET /fruit/kiwi.gif HTTP/1.1
Host: www.exotiquecuisine.com
If-modified-since: Wed, 7 Sep 2011 09:23:24
注意If-modified-since的值就是一周前Last-Modified的值。这个条件GET告诉服务器仅在对象在这个时间之后被修改的情况下才发送这个对象给我。
假定这个对象自从一周前没有被修改过,那么第4步:
- Web服务器就会发送一个响应报文
HTTP/1.1 304 Not Modified
Date: Sat, 15 Oct 2011 15:39:29
Server: Apache/1.3.0 (Unix)
(empty entity body)
我们可以看到,在回复条件GET时,web server依然发送 了一个响应报文但是并没有在响应消息中包含请求的对象。包含请求的对象会浪费带宽,增加用户感知响应时间。
注意,最后一条响应报文有一个304的状态码,意思是Not Modified。这也就告知了缓存它可以继续了,将这个对象的cached copy发送给请求的browser.
但是如果发生了修改,服务器将资源发给请求端。
电子邮件应用SMTP
简单邮件传输协议 Simple Mail Transfer Protocol ,尽管邮件服务器可以用SMTP发送、接收邮件,但是邮件客户端只能用SMTP发送邮件,接收邮件一般用IMAP 或者 POP3 。邮件客户端使用TCP的25号端口与服务器通信。
3个主要组成部分:
:::tip 🔔 用户代理
又名“邮件阅读器”
撰写、编辑和阅读邮件
如Outlook、Foxmail
输出和输入邮件保存在服务器上
:::
:::tip 🔔 邮件服务器
邮件中管理和维护发送给用户
输出报文队列保持待发送邮件报文
邮件服务器之间的SMTP协议:发送email报文
客户:发送方邮件服务器 服务器:接收端邮件服务器
:::
:::tip 🔔 简单邮件传输协议: SMTP
使用TCP在客户端和服务器之间传送报文,端口号为25
直接传输:从发送方服务器到接收方服务器
传输的3个阶段
握手
传输报文
关闭
命令/响应交互
命令:ascii文本
响应:状态码和状态信息
报文必须为7位ASCII码 :::
举例:
:::tip 🔔
1、发送方Alice调用用户代理并提供接收方Bob的邮箱地址,在用户代理上撰写待发送的报文,接着指示用户代理发送报文。
2、用户代理将Alice撰写的报文发送到Alice的邮件服务器,报文到达邮件服务器后将被分发到报文队列中。
3、运行在Alice的邮件服务器的SMTP客户端发现报文队列中的这个报文后将会创建一个到运行在Bob邮件服务器的SMTP服务器的TCP连接。
4、经过SMTP握手后,SMTP客户端通过TCP连接把报文发送出去。
5、在Bob的邮件服务器上,SMTP服务器接收到报文后,邮件服务器将报文放入Bob的邮箱里。
6、Bob有空时看到邮箱消息便调用用户代理查阅报文。
:::
SMTP总结
SMTP使用持久连接
SMTP要求报文(首部和主体)为7位ASCII编码
SMTP服务器使用 CRLF.CRLF决定报文的尾部
:::tip 🔔 SMTP和HTTP比较
HTTP: 拉(pull)
SMTP: 推(push)
二者都是ASCII形式的命令/响应交互、状态码
HTTP:每个对象封装在各自的响应报文中
SMTP:多个对象包含在一个报文中
:::
常见SMTP命令
指令 | 说明 |
---|---|
HELO | 与服务器确认,通知其客户端使用的机器名称,一般邮件服务器不做限定 |
AUTH | 使用AUTH LOGIN与服务器进行登录验证 |
FROM 发件人信息,填写与认证信息不同往往被定位为垃圾邮件或恶意邮件 | |
RCPT TO | 收信人地址 |
DATA | 输入邮件基本信息 |
FROM | 邮件基本信息:发信人显示信息(此处可以伪造身份,但是非常容易被识别) |
TO | 邮件基本信息:服务器收件人显示信息 |
SUBJECT | 邮件基本信息:邮件标题,不填写也往往容易被定位为垃圾邮件 |
QUIT | 断开链接 |
常见SMTP返回码
返回码 | 说明 |
---|---|
220 | 服务就绪 |
250 | 请求动作成功完成 |
235 | 认证通过 |
221 | 处理中 |
354 | 发送开始,往往与data指令结合 |
500 | 指令错误 |
550 | 命令无法执行 |
邮件报文格式
邮件访问协议
由于SMTP是一个PUSH(推)协议,所以接收方如何将邮件从位于ISP的邮件服务器上将邮件拉下来呢?
所以就产生了邮件访问协议,该协议将Bob的邮件服务器上的报文传给本地的PC。
常见的邮件访问协议:
POP:邮局访问协议-用户身份确认(代理<–>服务器)并下载
IMAP:Internet 邮件访问协议-更多特性(更复杂)并在服务器上处理存储的报文
HTTP:Hotmail, yahoo! Mail等比较方便
POP3 第三版邮局协议
当用户代理打开邮件服务器(服务器)端口110上的TCP连接后,POP3开始工作。POP3按照三个阶段工作,分别是:特许、事务处理、更新。
如果改变客户机,Bob不能阅读邮件
POP3在会话中是无状态的
:::tip 🔔 一、特许阶段
用户代理以明文形式发送用户名和口令来鉴别用户。
有两个主要的命令,user-username和pass-password。
客户端命令:
user:申明用户名
pass: 口令
服务器响应:
+OK
-ERR
:::
:::tip 🔔 二、事务处理 用户代理取回报文并对报文做删除标记。
list: 报文号列表
retr:根据报文号检索报文
dele:删除
quit
:::
:::tip 🔔 三、更新阶段 客户发出quit命令后,结束POP3绘画,邮件服务器删除那些被标记删除的报文。 :::
IMAP 因特网邮件访问协议
与IMAP服务器将每个报文与一个文件夹联系起来
允许用户用目录来组织报文
允许用户读取报文组件
IMAP在会话过程中保留用户状态:
目录名、报文ID与目录名之间映射