应用层协议原理
网络核心中没有应用层软件与功能
网络应用只在端系统上存在
网络应用的体系结构
客户-服务器(C/S)
服务器:
一直运行
固定的IP地址与端口号
扩展性差,负载达到一定程度后性能骤降
客户端:
主动与服务器通信,不直接与其它客户端通信
可能是动态IP地址
对等体(P2P)
(几乎)没有一直运行的服务器
任意端系统间可以通信,各节点既是客户端又是服务器
自扩展性——新peer节点带来新的服务能力与服务请求
参与的主机间歇性连接且可以改变IP地址(难以管理)
e.g. 迅雷
C/S与P2P混合体
Napster:
集中式文件搜索(资源的注册与查询在主机上),P2P式文件传输
即时通信:
集中式在线检测(向主机注册IP并查找在线用户位置),P2P式用户聊天
进程通信
进程:在主机上运行的应用程序
客户端进程:发起通信的进程
服务器进程:等待连接的进程
主机间按照应用层协议(借助传输层提供的服务)交换报文来通信
P2P架构中也分为客户端进程与服务器进程
进程的标识与寻址
进程通过IP+port标示,IP+port确定了端节点的位置(end point)
IP标识主机,port标识所采用的传输层协议(TCP与UDP所采用的端口范围不同)与端口号
本质上,一对主机进程间的通信由两个端节点构成
端口举例:HTTP——TCP 80;Mail——TCP 25;FTP——TCP 2
传输层提供的服务
应用层与传输层间的接口所携带的信息:
①要传输的报文(对于传输层而言——SDU)
②谁传的:IP+端口号
③传给谁:对方IP+端口号
传输层的TCP实体/UDP实体根据信息进行TCP报文段/UDP数据报的封装:
①端口与数据等
②将IP往下交IP实体,用于封装IP数据报
socket
socket代替繁琐的层间信息,是整数,是本地标示,类似Windows句柄
一个socket对应一个会话,TCP socket对应四元组(本机IP与端口+对方IP与端口),UDPsocket对应二元组(本机IP与端口)
应用层协议
定义了运行在不同端系统上的应用进程如何交换报文:
①交换的报文类型——请求和应答报文
②各种报文类型的语法——报文中的各个字段及其描述
③字段的语义——即字段取值的含义
④进程何时、如何发送报文及对报文进行响应的规则
应用协议是应用的组成部分,应用还由客户端、服务器、HTML等组成
公开协议(open):由RFC文档定义,例如HTTP、SMTP
专用(私有,dedicate)协议:协议不公开,例如Skype
传输层向应用层提供的服务:TCP服务、UDP服务
传输层向应用层提供服务的衡量指标:数据丢失率、延迟、吞吐、安全性等
SSL采用SSL库在TCP之上为应用层提供加密的TCP连接
Web与HTTP
Web页包含一个基本的HTML文件,HTML又包含若干个对象的引用(链接)
URL格式:
HTTP
超文本传输协议(Web的应用层协议),C/S(客户-服务器)模式
HTTP是无状态的,不维护关于客户的任何信息(支持更多客户端)
HTTP持久/非持久连接
非持久:一次连接请求与接受连接,一次请求报文与响应报文,随后断开。因此最多只有一个对象在TCP连接上发送,下载多个对象需要多个TCP连接。HTTP/1.0(RFC1945)使用非持久连接
持久:一次连接请求与接受连接,多次请求报文与响应报文。因此多个对象可以在一个(在客户端和服务器之间的)TCP连接上传输。HTTP/1.1(RFC2068)默认使用持久连接
响应时间模型:往返时间RTT(round-trip time)——一个小的分组从客户端到服务器,在回到客户端的时间(传输时间忽略)
非持久HTTP的一个文件传输时间为2RTT+传输时间
持久HTTP:
首先建立连接花费1RTT
①非流水方式——客户端只能在收到前一个响应后才能发出新的请求,每个引用对象花费一个RTT
②流水方式——HTTP/1.1的默认模式。客户端遇到一个引用对象就立即产生一个请求,所有引用(小)对象只花费一个RTT是可能的
HTTP请求报文
ASCII(人能阅读)
method:GET、POST、HEAD······
sp:空格
version:http协议版本
cr lf:换行
header field name:Host、User-agent······
entity body:实体。POST请求时提交的数据
User-Agent:用户代理,即UA,一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等
提交表单输入
POST方式:输入包含在实体(entity body)中,被提交到服务器
URL方式:通过GET方法,包含在URL字段中被提交到服务器
e.g. xx yy zzz_百度搜索
"?"连接URL与输入,"&"连接不同参数
参数名为wd cl,参数值为XX+YY+zzz 3
方法类型
GET(1.0/1.1):GET请求
POST(1.0/1.1):POST请求
HEAD(1.0/1.1):只请求HTTP的头部,通常用于维护
PUT(1.1):将实体主体中的文件上载到URL字段规定的路径,上传对象,通常用于维护
DELETE(1.1):删除URL字段规定的文件,删除对象,通常用于维护
HTTP响应报文
Content-Length:HTTP区分报文的开始与结尾。可能一端发送2个1k的报文,而另一端接收了1个2k的报文
状态码:200(OK)、301(Moved Permanently)、400(Bad Request,通用差错代码,表示请求无法处理)、404(Not Found,服务器找不到请求的数据)、505(HTTP Version Not Supported)
cookies:用户—服务器状态
组成部分:
①在首次HTTP响应报文中有一个cookie的首部行
②在随后的HTTP请求报文含有一个cookie的首部行
③在用户端系统中保留有一个cookie文件,由用户的浏览器管理
④在Web站点有一个后端数据库
用处:用户验证、推荐、维持状态(协议端节点、http报文携带状态信息)等
存在隐私问题
Web cache(Web缓存 代理服务器)
不访问原始服务器,就满足客户的请求
缓存既是客户端又是服务器,通常由ISP安装(大学、公司、居民区)
用处:①降低客户端的请求响应时间;②降低服务端负载
缓存更新:发送头部包含If-modified-since字段的请求报文
FTP(RFC959)
TCP传输协议,有状态连接,通过两个TCP连接客户端与FTP服务器,一个为控制连接(带外out of band传送),端口号为21,明文传递口令、命令;一个为数据连接,端口号为20,传递数据
用户代理:邮件应用
输出和输入的邮件都保存在服务器上
SMTP
用户代理向邮件服务器传输,邮件服务器之间的相互传输,使用SMTP协议(RFC2821)
客户端与服务器通过TCP连接,端口号为25,传输包括握手-传输报文-关闭三个阶段
命令与报文皆为ASCII码,且报文必须为7位ASCII码
SMTP使用持久连接,且多个对象包含在一个报文中(HTTP为每个对象包含在各自的响应报文中)
邮件访问协议
邮件访问采用POP3/IMAP/HTTP协议
POP3:会话无状态。下载并删除模式——邮件下载后从服务器删除;下载并保留模式——邮件下载后在服务器保留副本
IMAP:会话保留用户状态(目录名、报文ID与目录间的映射)。允许用户在服务器创建目录
DNS
域名解析系统 Domain Name System
分层的,基于域的
运行在UDP 53的应用服务,使用应用层协议
功能:
①负责主机名(“字符串”地址)与IP地址的转换
②主机/邮件服务器别名与规范名的转换
③负载均衡
DNS名字空间
DNS采用层次树状结构的命名方法
Internet根被划为几百个顶级域(e.g. 通用:.com; .edu,国家:.cn; .us),可再划分若干子域,树叶是主机
域名从本域往上,直到树根,以“.”分隔:www.hust.edu.cn
域的划分属于逻辑划分,而非物理划分:一个域的主机可以不在一个网络,一个网络的主机不一定在一个域
DNS维护与查询
资源记录(resource records)
维护域名-ip的映射关系,位于DNS的分布式数据库中
RR格式:
Domain_name:域名
TTL(time to live):生存时间(权威——永久保留数据;缓冲记录——规定时间后删除数据以便更新)
Class类别:对于Internet,值为IN
Value值:根据Type存储数字,域名或ASCII串(IP)
Type类别:
DNS查询
应用调用解析器(resolver)-解析器作为客户向DNS发出UDP查询报文-DNS返回响应报文(name/ip)
递归查询:
迭代查询:
DNS客户端与本地名称服务器间为递归,而本地名称服务器与其它名称服务器间是迭代
DNS协议:查询与响应报文的格式相同
DNS缓存、新增域与安全
DNS一旦学到一个映射,便缓存该映射,用于提高效率,通过TTL解决一致性问题(更新)
新增域:
①新域名向登记机构提供权威DNS服务器的名字与IP
②登记机构在TLD(顶级域服务器)中插入两条RR:域对应DNS服务器的NS类型记录,域对应IP的A类型记录
总的来说,DNS比较健壮
P2P
非结构化P2P
集中式目录:中心服务器保存节点信息(IP、内容),对等体间传输内容。存在单点故障、性能瓶颈、侵犯版权等问题。Napster
全分布式:无中心服务器,采用flooding算法(泛洪)广播查询相邻节点,节点再转发查询,通过TTL等方式限制查询深度。需要ping相邻节点且相邻节点返回pong。Gnutella
混合式(半分布式):每一组节点属于一个超级节点组成集中式网络,节点通过组内的超级节点访问其它超级节点进行查询。超级节点跟踪节点内容,转发查询到其它超级节点,并负责内容传输。KaZaA
结构化P2P(DHT)
类似一致性哈希算法
一个拓扑结构中的各个节点有唯一的哈希节点值,按照值的大小排序节点,每个节点维护一个值区间,区间包含对应的资源
CDN
内容分发网络Content Delivery Network
依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率
关键技术:内容存储与分发
简单来讲,CDN就是根据用户位置分配最近的资源,比如视频和图片资源,通过DNS完成请求转发和重定向
一致性问题:服务器内容修改后,需要通知到CDN服务商,并且更新其下的CDN服务器内容
DASH
多媒体流化服务Dynamic, Adaptive Streaming over HTTP
服务器:
将视频文件分割成多个块
每个块独立存储,编码于不同码率(8-10种)
告示文件(manifest file)——提供不同块的URL
客户端:
获取告示文件
周期性地测量服务器到客户端的带宽
查询告示文件,自行决定某一时刻向某一URL(CDN)请求一个块
①如果带宽足够,选择最大码率的视频块
②会话中的不同时刻,根据带宽或设定切换请求不同的编码块
Socket编程
socket套接字是操作系统提供操作「网络协议栈」的接口,抽象且实现了了TCP/IP协议。通过socket接口控制协议栈工作,从而实现网络通信
socket建立之后,消息的收发都通过socket,变得非常方便。Socket是双方会话关系的本地标识
tcp和udp各自用一套端口,哪怕都是8000,但是互不冲突
针对TCP协议,Socket是一个四元组(本地ip,本地port,对方ip,对方port)
Socket | IP | Port | IP | Port | PID |
针对UDP协议,Socket是一个二元组(本地ip,本地port)
Socket | IP | Port | PID |
端口用于区分应用进程(PID)。一个指定的端口号不能被多个应用程序共用,但父子进程间、线程间可进行socket共享(应用程序内部不同socket可使用同一端口)
很多防火墙只允许特定目标端口的数据包通过
TCP套接字编程
服务器端流程:
1.创建服务器套接字(ServerSocket)
2.将套接字绑定到一个本地IP和端口上(bind)
3.将套接字设定为监听模式,准备接受客户端请求(listen)
4.阻塞(程序不继续执行)等待客户端请求到来。当请求到来后,接受连接请求,返回一个新的对应于此客户端连接的套接字socketClient(accept)
5.用返回的套接字socketClient和客户端进行通信(IO流操作)
6.返回,等待另一个客户端请求(accept)
7.关闭套接字(close)
1 2 3 4 5 6 7 8 9 | tcps = socket() #创建服务器套接字 tcps.bind() #把地址绑定到套接字 tcps.listen() #监听链接 while True: #服务器无限循环 tcpc = tcps.accept() #接受客户端链接 while True: #通讯循环 tcpc.recv()/tcpc.send() #对话(接收与发送) tcpc.close() #关闭客户端套接字 tcps.close() #关闭服务器套接字(可选) |
客户端流程:
1.创建客户端套接字(Socket)
2.向服务器发出连接请求(connect)
3.和服务器进行通信(IO流操作)
4.关闭套接字(close)
1 2 3 4 5 | tcpc = socket() # 创建客户端套接字 tcpc.connect() # 尝试连接服务器 while True: # 通讯循环 tcpc.send()/tcpc.recv() # 对话(发送/接收) tcpc.close() # 关闭客户套接字 |
UDP套接字编程
服务器端流程:
1.创建套接字(DatagramSocket)
2.将套接字绑定到一个本地地址和端口上(bind)
3.阻塞等待接收消息(receive)
4.收到的消息被封装在DatagramPacket里,里面有对方的ip和端口
5.可以根据对方的DatagramPacket再像对方发送消息
6.关闭套接字(close)
客户端流程:
1.创建客户端套接字(Socket)
2.创建交互数据报(DatagramPacket),并指定对方ip和端口
3.发送消息(send)
4.关闭套接字(close)