@TOC
网络应用体系结构
客户机/服务器
服务器:
- 7*24小时提供服务
- 永久性访问地址/域名
- 利用大量服务器实现可扩展性
客户机:
- 与服务器通信,使用服务器提供的服务
- 间歇性接入网络
- 可能使用动态IP地址
- 不会与其他客户机直接通信
P2P
- 没有永远在线的服务器
- 任意端系统/节点之间可以直接通讯
- 节点间歇性接入网络
- 节点可能改变IP地址
- 优点:高度可伸缩
- 缺点:难于管理
混合结构
举例:Napster应用
- 文件传输使用P2P结构
- 文件的搜索采用C/S结构——集中式
①每个节点向中央服务器登记自己的内容
②每个节点向中央服务器提交查询请求,查找感兴趣的内容
网络应用进程通信
进程:
- 主机上运行的程序
同一主机上运行的进程之间如何通信?
- 进程间通信机制
- 操作系统提供
不同主机上运行的进程间如何通信?
- 消息交换
进程间通信利用socket发送/接收消息实现:
类似于寄信:
- 发送方将消息送到门外邮箱
- 发送方依赖(门外的)传输基础设施将消息传到接收方所在主机,并送到接收方的门外
- 接收方从门外获取消息
传输基础设施向进程提供API:
- 传输协议的选择
- 参数的设置
如何寻址进程?
- 不同主机上的进程间通信,那么每个进程必须拥有标识符
- 为了区分不同主机需要使用IP地址。
- 为了区别主机上的不同进程需要为主机上每个需要通信的进程分配一个端口号 。 例如:HTTP Server: 80,Mail Server:25。
- 因此进程的标识符为:IP地址+端口号。
应用层协议: 网络应用需遵循应用层协议:
- 公开协议 由RFC(Request For Comments)定义, 允许互操作,如HTTP, SMTP等。
- 私有协议 多数P2P文件共享应用
应用层协议的内容:
- 消息的类型(type) ①请求消息 ② 响应消息
- 消息的语法(syntax)/格式 ①消息中有哪些字段(field)? ②每个字段如何描述
- 字段的语义(semantics) ① 字段中信息的含义
- 规则(rules) ① 进程何时发送/响应消息 ②进程如何发送/响应消息
网络应用的服务需求
- 数据丢失(data loss)/可靠性(reliability) ① 某些网络应用能够容忍一定的数据丢失:网络电话 ②某些网络应用要求100%可靠的数据传输:文件传输,telnet
- 时间(timing)/延迟(delay) ①有些应用只有在延迟足够低时才“有效” ② 网络电话/网络游戏
- 带宽(bandwidth) ① 某些应用只有在带宽达到最低要求时才“有效”:网络视频 ② 某些应用能够适应任何带宽——弹性应用:email
Internet传输层服务模型
TCP
TCP服务
- 面向连接: 客户机/服务器进程间需要建立连接
- 可靠的传输
- 流量控制: 发送方不会发送速度过快,超过接收方的处理能力
- 拥塞控制: 当网络负载过重时能够限制发送方的发送速度
- 不提供时间/延迟保障
- 不提供最小带宽保障
UDP
UDP服务
- 无连接
- 不可靠的数据传输
- 不提供: ① 可靠性保障 ②流量控制 ③拥塞控制 ④延迟保障 ⑤带宽保障
特定网络应用及协议
HTTP
简述:
- WWW (World Wide Web,万维网)是存储在Internet计算机中、数量巨大的文档的集合。这些文档称为页面,它是一种超文本(Hypertext)信息,可以用于描述超媒体。文本、图形、视频、音频等多媒体,称为超媒体( Hypermedia)。
- Web上的信息是由彼此关联的文档组成的,而使其连接在一起的是超链接( Hyperlink)。
网页(Web Page)包含多个对象(objects):
- 对象:HTML文件、JPEG图片、视频文件、动态脚本等。
- 其中基本HTML文件:包含对其他对象引用的链接
- 对象的寻址(addressing)通过 URL(Uniform Resoure Locator):统一资源定位器 RFC1738
总结:
-
万维网应用遵循超文本传输协议( HyperText Transfer Protocol)。
使用C/S结构:
- 客户—Browser:请求、接收、展示Web对象
- 服务器—Web Server:响应客户的请求,发送对象
使用TCP传输服务:
- 服务器在80端口等待客户的请求
- 浏览器发起到服务器的TCP连接(创建套接字Socket)
- 服务器接受来自浏览器的TCP连接
- 浏览器(HTTP客户端)与Web服务器(HTTP服务器)交换HTTP消息
- 关闭TCP连接
无状态(stateless):
- 服务器不维护任何有关客户端过去所发请求的信息
HTTP连接
HTTP连接的两种类型:
- 非持久性连接(NonpersistentHTTP) ①每个TCP连接最多允许传输一个对象 ② HTTP 1.0版本使用非持久性连接
- 持久性连接(Persistent HTTP) ① 每个TCP连接允许传输多个对象 ② HTTP 1.1版本默认使用持久性连接
非持久连接:
响应时间分析与建模:
RTT(Round Trip Time): 从客户端发送一个很小的数据包到服务器并返回所经历的时间
响应时间(Response time):
-
发起、建立TCP连接:1个RTT
-
发送HTTP请求消息到HTTP响应消息的前几个字节到达:1个RTT
-
响应消息中所含的文件/对象传输时间
Total=2RTT +文件发送时间
持久性HTTP: 非持久性连接的问题:
- 每个对象需要2个RTT
- 操作系统需要为每个TCP连接开销资源(overhead)
- 浏览器会打开多个并行的TCP连接以获取网页所需对象, 给服务器端造成巨大压力。
持久性连接:
- 发送响应后,服务器保持TCP连接的打开
- 后续的HTTP消息可以通过这个连接发送
无流水(pipelining)的持久性连接:
- 客户端只有收到前一个响应后才发送新的请求
- 每个被引用的对象耗时1个RTT
带有流水机制(流水机制 :不停地工作 (速度快))的持久性连接:
- 即HTTP客户可以一个接 一个挨着发送各个引用对象的请求。
- HTTP 1.1的默认选项
- 客户端只要遇到一个引用对象就尽快发出请求
- 理想情况下,收到所有的引用对象只需耗时约1个RTT
HTTP消息格式
HTTP协议有两类消息:
- 请求消息(request)
- 响应消息(response)
上传输入的方法:
- POST方法 ① 网页经常需要填写表格(form) ② 在请求消息的消息体(entity body)中上传客户端的输入
- URL方法 ① 使用GET方法 ② 输入信息通过request行的URL字段上传
方法类型:
- HTTP/1.0 ① GET ②POST ③ HEAD 请Server不要将所请求的对象放入响应消息中
- HTTP/1.1 ①GET, POST, HEAD ②PUT 将消息体中的文件上传到URL字段所指定的路径 ③DELETE 删除URL字段所指定的文件
HTTP响应状态代码(位于响应消息的第一行)。举例:
200 :请求成功,成功返回网页 301 :资源(网页等)被永久转移到其它URL 302 :资源(网页等)被临时转移到其它URL 304 :请求未修改、命中缓存 401 :未授权 403 :服务器拒绝请求 404 :请求的网页或资源不存在 500 :内部服务器错误,无法完成请求 502 :错误网关 503 :请求未完成,服务器临时过载或宕机 504 :网关超时
Cookie技术
为什么需要Cookie?
- HTTP协议无状态很多应用需要服务器掌握客户端的状态
Cookie技术:
- 某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。
Cookie的组件:
- HTTP响应消息的cookie头部行
- HTTP请求消息的cookie头部行
- 保存在客户端主机上的cookie文件,由浏览器管理
- Web服务器端的后台数据库
Cookie的作用:
- 身份认证
- 购物车
- 推荐
- Web e-mail
Web缓存/代理服务器技术
功能:
- 在不访问服务器的前提下满足客户端的HTTP请求。
为什么要发明这种技术?
- 缩短客户请求的响应时间
- 减少机构/组织的流量
- 在大范围内(Internet)实现有效的内容分发
Web缓存/代理服务器:
- 用户设定浏览器通过缓存进行Web访问
- 浏览器向缓存/代理服务器发送所有的HTTP请求 ①如果所请求对象在缓存中,缓存返回对象 ②否则,缓存服务器向原始服务器发送HTTP请求,获取对象,然后返回给客户端并保存该对象
- 缓存既充当客户端,也充当服务器
- 一般由ISP(Internet服务提供商)架设
条件性GET方法:
目标:
- 如果缓存有最新的版本,则不需要发送请求对象
缓存:
- 在HTTP请求消息中声明所持有版本的日期
- If-modified-since: <date>
服务器:
- 如果缓存的版本是最新的,则响应消息中不包含对象
- HTTP/1.0 304 Not Modified
SMTP, POP, IMAP
Email应用
Email应用的构成组件:
- 邮件客户端(user agent)
- 邮件服务器
- SMTP协议(Simple Mail Transfer Protocol)
邮件客户端:
- 读、写Email消息
- 与服务器交互,收、发Email消息
- Outlook, Foxmail, Thunderbird
- Web客户端
邮件服务器(Mail Server):
- 邮箱:存储发给该用户的Email
- 消息队列(message queue):存储等待发送的Email
SMTP协议:
- 邮件服务器之间传递消息所使用的协议
- 客户端:发送消息的服务器
- 服务器:接收消息的服务器
SMTP协议:
- 使用TCP进行email消息的可靠传输
- 端口25
- 传输过程的三个阶段 ①握手 ②消息的传输 ③关闭
- 命令/响应交互模式 ①命令(command): ASCII文本 ② 响应(response): 状态代码和语句
- 使用持久性连接
- 要求消息必须由7位ASCII码构成
- SMTP服务器利用CRLF.CRLF确定消息的结束。
SMTP协议与HTTP对比:
- HTTP: 拉式(pull)
- SMTP: 退式(push)
- 都使用命令/响应交互模式
- 命令和状态代码都是ASCII 码
- HTTP: 每个对象封装在独立的响应消息中
- SMTP: 多个对象在由多个部分构成的消息中发送
Email消息格式:多媒体扩展:
- MIME:多媒体邮件扩展 RFC 2045, 2056通过在邮件头部增加额外的行以声明MIME的内容类型
邮件访问协议(从服务器获取邮件):
- POP: Post Office Protocol [RFC 1939] ①认证/授权(客户端,服务器)和下载
- IMAP: Internet Mail Access Protocol [RFC 1730] ① 更多功能 ②更加复杂 ③能够操纵服务器上存储的消息
- HTTP:163, QQ Mail等。
POP协议
- “下载并删除”模式 ①用户如果换了客户端软件,无法重读该邮件
- “下载并保持”模式:不同客户端都可以保留消息的拷贝
- POP3是无状态的
IMAP协议
- 所有消息统一保存在一个地方:服务器
- 允许用户利用文件夹组织消息
- IMAP支持跨会话(Session)的用户状态: ①文件夹的名字 ② 文件夹与消息ID之间的映射等
DNS
域名和IP地址之间使用域名解析系统DNS进行映射:
- 多层命名服务器构成的分布式数据库
- 应用层协议:完成名字的解析 ① Internet核心功能,用应用层协议实现 ②网络边界复杂
DNS服务:
- 域名向IP地址的翻译
- 主机别名
- 邮件服务器别名
- 负载均衡:Web服务器
为什么不使用集中式的DNS?
- 单点失败问题
- 流量问题
- 距离问题
- 维护性问题
分布式层次式数据库:
DNS根域名服务器:
- 本地域名解析服务器无法解析域名时,访问根域名服务器
- 根域名服务器 ①如果不知道映射,访问权威域名服务器 ②获得映射 ③向本地域名服务器返回映射
TLD顶级域名服务器和权威域名解析服务器:
- 顶级域名服务器(TLD, top-level domain): 负责com, org, net,edu等顶级域名和国家顶级域名,例如cn,uk, fr等 。 ① Network Solutions维护com顶级域名服务器 ②Educause维护edu顶级域名服务器
- 权威(Authoritative)域名服务器:组织的域名解析服务器,提供组织内部服务器的解析服务 ① 组织负责维护 ② 服务提供商负责维护
本地域名解析服务器:
- 不严格属于层级体系
- 每个ISP有一个本地域名服务器 ① 默认域名解析服务器
- 当主机进行DNS查询时,查询被发送到本地域名服务器 ①作为代理(proxy),将查询转发给(层级式)域名解析服务器系统
DNS记录缓存和更新:
- 只要域名解析服务器获得域名—IP映射,即缓存这一映射 ① 一段时间过后,缓存条目失效(删除) ② 本地域名服务器一般会缓存顶级域名服务器的映射。因此根域名服务器不经常被访问
- 记录的更新/通知机制 ① RFC 2136 ②Dynamic Updates in the Domain Name System (DNS UPDATE)
过程描述如下:
- 浏览器中输入www.qq.com域名,操作系统检查本地hosts文件中是否有这个网址映射关系,如果有则使用映射IP,完成解析 ①hosts文件的用途:将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的IP地址。 ②当建立dns服务器的时候,或者要搭建本地网的时候就用的着了,可以用来屏蔽广告和木马。 ③一旦找到,系统会立即打开相应的网页,如果没有找到,则系统会将url提交到DNS服务器进行IP地址解析。
- host文件中没有这个域名映射,则查找本地DNS解析器缓存,过程同1
- 如果DNS解析器缓存中也没有该域名映射,则会发请求从本地DNS服务器(运营商维护)查询映射关系,如果本地DNS服务器区域配置文件中包含了该域名,则返回解析结果给客户机,完成域名解析。
- 如果本地DNS服务器中也没有该域名映射,则会把请求转发给13台根服务器。根DNS服务器收到请求,判断.com是谁管理,就把.con顶级域服务器的IP返回本地DNS服务器,然后本地服务器又会联系.com服务器,这台服务器又会找到.qq.com域名对应服务器的IP地址给本地DNS服务器,最后本地服务器又会联系.qq.com域名服务器,该服务器找到www.qq.com对应的服务器IP返回给本地服务器。
- 本地服务器把域名映射的服务器IP返回给用户电脑,并且包这个映射关系保存在缓存中,以备下次用户查询时可以直接返回结果。
DNS问题
Q:这里有个问题,为什么全球只有13台根DNS服务器呢?
A: 域名解析服务中使用了UDP和TCP协议。 DNS用于查询和响应,而TCP用于主服务器和从服务器之间的区传送
而UDP实现中能保证正常工作的最大包长是512字节,就是这个512字节限制了根服务器的数量,一个512字节的UDP数据包最多只能包含13台服务器的信息。
Q:既然UDP对传输数据大小有限制,为什么还要用UDP协议呢?
A: 因为一次UDP通信可以短到2个数据包:一个查询包,一个响应包。 而一次TCP通信至少包含9个包:三次握手建立TCP连接,一个查询包,一个响应包,最后四次挥手断开TCP连接。 相比之下,UDP效率会高很多,所以采用UDP协议通信。
P2P应用
纯P2P架构:
- Peer-to-peer
- 没有服务器
- 任意端系统之间直接通信
- 节点阶段性接入Internet
- 节点可能更换IP地址
Socket编程
应用编程接口API:
- 就是应用进程的控制权和操作系统的控制权进行转换的一个系统调用接口。
- Socket不属于协议范畴,而是一个调用接口(API),Socket是对TCP/IP协议的封装,通过调用Socket,才能使用TCP/IP协议。Socket连接是长连接,理论上客户端和服务器端一旦建立连接将不会主动断开此连接。Socket连接属于请求-响应形式,服务端可主动将消息推送给客户端。
几种典型的应用编程接口:
- Berkeley UNIX 操作系统定义了一种 API,称为套接字接口(socket interface),简称套接字(socket)。
- 微软公司在其操作系统中采用了套接字接口 API ,形成了一个稍有不同的 API,并称之为 Windows SocketInterface,WINSOCK。
- AT&T 为其 UNIX 系统 V 定义了一种 API,简写 为 TLI (Transport Layer Interface)。
标识通信端点(对外):
- IP地址+端口号
操作系统/进程如何管理套接字(对内)?
- 套接字描述符(socket descriptor):小整数
Socket API函数(C语言编写)
- 使用Socket的应用程序在使用Socket之前必须首先调用WSAStartup函数。
- 应用程序在完成对请求的Socket库的使用, 最后要调用WSACleanup函数。
- socket创建套接字,操作系统返回套接字描述符(sd)。
① 第一个参数(协议族): protofamily = PF_INET(TCP/IP)
②第二个参数(套接字类型):type = SOCK_STREAM,SOCK_DGRAM or SOCK_RAW(TCP/IP)
③第三个参数(协议号):0为默认
④TCP:可靠、面向连接、字节流传输、点对点 ⑤UDP:不可靠、无连接、数据报传输
- Closesocket关闭一个描述符为sd的套接字。
- bind绑定套接字的本地端点地址: IP地址+端口号。 ①参数: 套接字描述符(sd) ② 端点地址(localaddr) :结构sockaddr_in
- listen:置服务器端的流套接字处于监听状态 ①仅服务器端调用 ②仅用于面向连接的流套接字
- connect:客户程序调用connect函数来使客户套接字(sd)与特定计算机的特定端口(saddr)的套接字(服务)进行连接。 ①仅用于客户端 ② 可用于TCP客户端也可以用于UDP客户端 ③ TCP客户端:建立TCP连接 ④ UDP客户端:指定服务器端点地址
- accept:服务程序调用accept函数从处于监听状态的流套接字sd的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道。 ①仅用于TCP套接字 ② 仅用于服务器
- recv:接收数据。 ①用于TCP套接字 ②用于连接模式的客户端UDP套接字
网络应用的Socket API(TCP)调用基本流程:
Socket编程-客户端软件设计
TCP客户端软件流程:
- 确定服务器IP地址与端口号
- 创建套接字
- 分配本地端点地址(IP地址+端口号)
- 连接服务器(套接字)
- 遵循应用层协议进行通信
- 关闭/释放连接
UDP客户端软件流程:
- 确定服务器IP地址与端口号
- 创建套接字
- 分配本地端点地址(IP地址+端口号)
- 指定服务器端点地址,构造UDP数据报
- 遵循应用层协议进行通信
- 关闭/释放套接字
Socket编程-服务器软件设计
4种类型基本服务器:
- 循环无连接(Iterative connectionless)服务器
- 循环面向连接(Iterative connection-oriented)服务器
- 并发无连接(Concurrent connectionless)服务器
- 并发面向连接(Concurrent connection-oriented)服务器
循环无连接服务器基本流程:
- 创建套接字
- 绑定端点地址(INADDR_ANY+端口号)
- 反复接收来自客户端的请求
- 遵循应用层协议,构造响应报文,发送给客户
循环面向连接服务器基本流程:
- 创建(主)套接字,并绑定熟知端口号;
- 设置(主)套接字为被动监听模式,准备用于服务器;
- 调用accept()函数接收下一个连接请求(通过主套接字),创建新套接字用于与该客户建立连接;
- 遵循应用层协议,反复接收客户请求,构造并发送响应(通过新套接字)
并发无连接服务器基本流程: 主线程1: 创建套接字,并绑定熟知端口号; 主线程2: 反复调用recvfrom()函数,接收下一个客户请求,并创建新线程处理该客户响应; 子线程1: 接收一个特定请求; 子线程2: 依据应用层协议构造响应报文,并调用sendto()发送; 子线程3: 退出(一个子线程处理一个请求后即终止)
并发面向连接服务器基本流程: 主线程1: 创建(主)套接字,并绑定熟知端口号; 主线程2: 设置(主)套接字为被动监听模式,准备用于服务器; 主线程3: 反复调用accept()函数接收下一个连接请求(通过主套接字),并创建一个新的子线程处理该客户响应; 子线程1: 接收一个客户的服务请求(通过新创建的套接字); 子线程2: 遵循应用层协议与特定客户进行交互; 子线程3: 关闭/释放连接并退出(线程终止).
Socket与Servlet的关系
- Socket:使用TCP/IP或者UDP协议在服务器与客户端之间进行传输的技术,是网络编程的基础
- Servlet:使用http协议在服务器与客户端之间通信的技术。是Socket的一种应用。
- tcp/ip协议:关注的是客户端与服务器之间的数据传输是否成功(三次握手,传输失败会重发)
- http协议:是在tcp/ip协议之上进一步封装的一层协议,关注的事数据传输的格式是否规范,底层的数据传输还是运用了socket和tcp/ip
- http的请求(request)和响应(response)分别被服务器封装成HttpServletRequest和HttpServletResponse对象。Http协议的内容可以通过这两个对象中的方法得到。在web工程中的类继承HttpServlet类后,服务器调用doGet/doPost方法时,封装好的HttpServletRequest和HttpServletResponse对象会作为参数传递给doGet/doPost方法。