学习自哈尔滨工业大学,应用层
bit 比特 或 位 1b
Byte 字节 1B
1B = 8b 一个字节等于8位
Mbps(Million bits per second)Mb/s 兆比特每秒。即“传输速率”,带宽。营业厅的网线带宽说的“几兆”是指多少Mbps而不是MB/s
1 Kbps = $10^3$ bps
1 Mbps = $10^6$ bps
1B/s = 8 bps
8 Mbps = 1 MB/s 但实际情况中8M的宽带往往达不到1MB/s的速度
概述
计算机网络=通信技术+计算机技术
通信系统模型:
计算机网络是一种通信网络
定义:计算机网络就是互连的、自治的计算机网络集合
自治:无主从关系
互连:互联互通,通信链路
交换网络
Internet
全球最大的互联网络 ISP(Internet Service Provider)
组成方面:
- 庞大的计算设备集合:主机(hosts)= 端系统(end systems),运行各种网络应用
- 通信链路:光纤,无线电,卫星。。。
- 分组交换:路由器(routers)、交换机(switches)
服务方面:
- 为网络应用提供通信服务的通信基础设施
- 为网络应用提供应用编程接口(API)
协议
硬件(主机、路由器、通信链路等)是计算机网络的基础。
计算机网络中的数据交换必须遵守事先约定好的规则。
网络协议(network protocol),简称为协议,是为进行网络中的数据交换而建立的规则、标准或约定。
规定了通信实体之间所交换的消息的格式、意义、顺序以及针对收到信息或发生的事件所采取的“动作”(actions)
三要素:
- 语法(Syntax)
- 数据域控制信息的结构或格式
- 信号电平(操作系统层面)
- 语义(Semantics)
- 需要发出何种控制信息
- 完成何种动作以及做出何种响应
- 差错控制
- 时序(Timing)
- 事件顺序
- 速度匹配
计算机网络结构
网络边缘:
客户/服务器(client/server)应用模型
- 客户发送请求,接收服务器响应
- 如:Web应用,文件传输FTP应用
对等(peer-peer,P2P)应用模型
- 无(或不仅依赖)专用服务器
- 通信在对等实体之间直接进行
- 如:QQ,Skype
接入网络:
数字用户线路(DSL):独占
电缆网络
机构(企业)接入网络(Ethernet)
无线接入网络
网络核心:
Internet结构
网络之网络
端系统通过接入ISP(access ISPs )连接到Internet
接入ISP必须进一步互连,这样任意两个主机才可以互相发送分组
内容提供商网络(content provider networks,如: Google, Microsoft等)可能运行其自己的网络,并就近为端用户提供服务、内容。
网络核心之数据交换
交换的含义:
动态转接
动态分配传输资源
数据交换的类型:
1、电路交换:
最典型电路交换网络:电话网络
电路交换的三个阶段:
- 建立连接(呼叫/电路建立)
- 通信
- 释放连接(拆除电路)
特点:独占资源
电路交换网络如何共享中继线?— 多路复用(Multiplexing)
2、报文交换(message switching)
报文:源(应用)发送的信息整体。比如:一个文件
存储&转发 :路由器需要接收到完整的整个数据报文后,才能开始向下一跳发送
3、分组交换(package switching)
分组:报文分拆出来的一系列相对较小的数据包
分组交换需要报文的拆分与重组,可能还会增加一个头部信息
产生额外开销
分组交换:统计多路复用(Statistical Multiplexing)
存储-转发(store-and-forward)
报文交换与分组交换均采用存储-转发交换方式
区别:
- 报文交换以完整报文进行“存储-转发”
- 分组交换以较小的分组进行“存储-转发
分组交换VS报文交换
报文交换:
- 报文长度为M bits
- 链路带宽为R bps
- 每次传输报文需要 M/R 秒
分组交换:
- 报文被拆分为多个分组
- 分组长度为 L bits
- 每个分组传输时延为L/R秒
分组交换的报文交付时间:
报文:M bits,链路带宽(数据传输速率):R bps,分组长度(大小):L bits
跳步数:h,路由器数:n = h - 1
$T = M / R + (h-1)L/R = M/R+nL/R$
分组交换VS电路交换
分组交换适用于突发数据传输网络
- 资源充分共享
- 简单、无需呼叫建立
可能产生拥塞(congestion): 分组延迟和丢失
- 需要协议处理可靠数据传输和拥塞控制
如何提供电路级性能保障? 例如:音/视频应用所需的带宽保障
多路复用
多路复用(multiplexing),简称复用,是通信技术中的基本概念
多路复用(Multiplexing):链路/网络资源(如带宽)划分为“资源片”
将资源片分配给各路“呼叫”(calls)
每路呼叫独占分配到的资源片进行通信
资源片可能“闲置”(idle) (无共享)
典型多路复用方法:
1、频分多路复用(frequency division multiplexing-FDM)
频分多路复用的各用户占用不同的带宽资源(请注意,这里的“带宽”是频率带宽(单位:Hz)而不是数据的发送速率)
用户在分配到一定的频带后,在通信过程中自始至终都占用这个频带
2、时分多路复用(time division multiplexing-TDM)
时分复用则是将时间划分为一段段等长的时分复用帧(TDM 帧),每个用户在每个 TDM 帧中占用固定序号的时隙
每用户所占用的时隙是周期性出现(其周期就是TDM 帧的长度)
时分复用的所有用户是在不同的时间占用相同的频带宽度
3、波分多路复用(Wavelength division multiplexing-WDM)
波分复用就是光的频分复用
4、码分多路复用(Code division multiplexing-CDM)
广泛应用于无线链路共享 (如蜂窝网,卫星通信等)
每 个 用 户 分 配 一 个唯 一 的 m bit 码片序列(chippingsequence),其中“0”用“-1”表示、“1”用“+1”表示,例如:S 站的码片序列:(–1 –1 –1 +1 +1 –1 +1 +1)
各用户使用相同频率载波,利用各自码片序列编码数据
编码信号 = (原始数据) × (码片序列)
如发送比特 1(+1),则发送自己的 m bit 码片序列
如发送比特 0(-1),则发送该码片序列的m bit 码片序列的反码
各用户码片序列相互正交(orthogonal)
网络性能
速率和带宽
速率即数据率(data rate)或称数据传输速率或比特率(bit rate)
- 单位时间(秒)传输信息(比特)量
- 计算机网络中最重要的一个性能指标
- 单位:b/s(或bps)、kb/s、Mb/s、Gb/s
- $k=10^3$ $M=10^6$ $G=10^9$
速率往往是指额定速率或标称速率,实际中一般达不到
带宽(bandwidth)原本指信号具有的频带宽度,即最高频率与最低频率之差,单位是赫兹(Hz)
网络的“带宽”通常是数字信道所能传送的最高数据率,单位:b/s (bps)
常用单位:kb/s ($10^3$ b/s)、Mb/s($10^6$ b/s)、Gb/s($10^9$ b/s)、Tb/s($10^{12}$ b/s)
包转发率
包转发率(PPS):全称是Packet Per Second(包/秒),表示交换机或
路由器等网络设备以包为单位的转发速率
线速转发:交换机端口在满负载的情况下,对帧进行转发时能够达到该端口线路的最高速度
延迟/时延
发生情况:
分组在路由器缓存中排队
- 分组到达速率超出输出链路容量时
- 分组排队,等待输出链路可用
四种分组延迟:
传输时延(transmission delay):数据从结点进入到传输媒体所需要的时间,传输时延又称为发送时延
传播时延(propagation delay):电磁波在信道中需要传播一定距离而花费的时间
处理时延(processing delay):主机或路由器在收到分组时,为处理分组(例如分析首部、提取数据、差错检验或查找路由)所花费的时间
排队时延(queueing delay):分组在路由器输入输出队列中排队等待处理所经历的时延
RTT
往返时延RTT(Round-Trip Time)
从发送方发送数据开始,到发送方收到 来自接收方的确认,经历的总时间
可用于判断网络的通断性、测试网络时 延、计算数据包丢失率等
时延带宽积
链路的时延带宽积又称为以比特为单位的链路长度
时延带宽积 = 传播时延 x 带宽 = $d_{prop}\times R$ (bits)
丢包率
队列缓存容量有限
分组到达已满队列将被丢弃 (即丢包)
丢弃分组可能由前序结点或源重发(也可能不重发)
丢包率 = 丢包数 / 已发分组总数
吞吐量/率
吞吐量:表示在发送端与接收端之间传送数据速率 (b/s)
即时吞吐量:给定时刻的速率
平均吞吐量:一段时间的平均速率
时延抖动
变化的时延称为抖动(Jitter)
时延抖动起源于网络中的队列或缓冲,抖动难以精确预测
在语音、视频多媒体业务中,抖动往往会严重影响用户的体验
体系结构
网络体系结构是从功能上描述计算机网络结构,即不关心物理的具体实现。
计算机网络体系结构简称网络体系结构(network architecture)是分层结构
每层遵循某个/些网络协议完成本层功能
计算机网络体系结构是计算机网络的各层及其协议的集合
体系结构是一个计算机网络的功能层次及其关系的定义
体系结构是抽象的
分层结构的优点:
结构清晰,有利于识别复杂系统的部件及其关系
- 分层的参考模型(reference model )
模块化的分层易于系统更新、维护
- 任何一层服务实现的改变对于系统其它层都是透明的
有利于标准化
不利之处:分层较多会导致效率变低,不同层之间存在信息冗余
注:透明在这里表示不可见的,类似于玻璃透明,所以看不见,很奇怪但就是这样实体(entity)表示任何可发送或接收信息的硬件或软件进程
协议是控制两个对等实体(即同一层)进行通信的规则的集合,协议是“水平的”。
任一层实体需要使用下层服务,遵循本层协议,实现本层功能,向上层提供服务,服务是“垂直的”。
同系统的相邻层实体间通过接口进行交互,通过服务访问点 SAP(Service Access Point),交换原语,指定请求的特定服务。
OSI参考模型(七层)
开放系统互连 (OSI)参考模型是由国际标准化组织 (ISO) 于1984年提出的分层网络体系结构模型。
目的是支持异构网络系统的互联互通,是异构网络系统互连的国际标准
理解网络通信的最佳学习工具(理论模型):理论成功,市场失败
7层(功能),每层完成特定的网络功能
- 应用层(Application)
- 表示层(Presentation)
- 会话层(Session)
- 传输层(Transport)
- 网络层(Network)
- 数据链路层(Data link)
- 物理层(Physical)
通信过程:主机要实现7层的功能,中间系统要实现底三层的功能,上四层称为端-端层
数据封装:
PDU:协议数据单元
数据封装的原因:
- 增加控制信息,构造协议数据单元(PDU)
控制信息主要包括
- 地址(Address):标识发送端/接收端
- 差错检测编码(Error-detecting code):用于差错检测或纠正
- 协议控制(Protocol control):实现协议功能的附加信息,如:优先级(priority)、服务质量(QoS)、安全控制等
物理层功能
接口特性
- 机械特性、电气特性、功能特性、规程特性
比特编码
- 数据率
- 比特同步
- 时钟同步
- 传输模式
- 半工(Simplex)
- 半双工(half-duplex)
- 全双工(full-duplex)
数据链路层功能
负责结点-结点(node-to-node)数据传输
组帧(Framing)
物理寻址(Physical addressing)
在帧头中增加发送端和/或接收端的物理地址标识数据帧的发送端和/或接收端
流量控制(Flow control):避免淹没客户端
差错控制(Error control):检测并重传损坏或丢失帧,并避免重复帧
访问(接入)控制(Access control):在任一给定时刻决定哪个设备拥有链路(物理介质)控制使用权
网络层功能
负责源主机到目的主机数据分组(packet)交付,该过程可能穿越多个网络
逻辑寻址(Logical addressing)
- 全局唯一逻辑地址,确保数据分组被送达目的主机,如IP地址
路由(Routing)
- 路由器(或网关)互连网络,并路由分组至最终目的主机
- 路径选择
分组转发
传输层功能
负责源-目的(端-端)(进程间) 完整报文传输
分段与重组
SAP寻址:确保将完整报文提交给正确进程,如端口号
连接控制
流量控制
差错控制
会话层功能
- 对话控制(dialog controlling):建立和维护
- 同步(synchronization):在数据流中插入“同步点”
表示层功能
处理两个系统间交换信息的语法与语义(syntax and semantics )问题
- 数据表示转化:转换为主机独立的编码
- 加密/解密
- 压缩/解压缩
应用层功能
- 支持用户通过用户代理(如浏览器)或网络接口使用网络(服务)
- 典型应用层服务:
- 文件传输(FTP)
- 电子邮件(SMTP)
- Web(HTTP)
TCP/IP参考模型(四层)
Everything over IP:IP可为各式各样的应用程序提供服务
IP over Everything:IP可应用到各式各样的网络上
5层参考模型
综合 OSI 和 TCP/IP 的优点
- 应用层:支持各种网络应用
- FTP, SMTP, HTTP
- 传输层:进程-进程的数据传输
- TCP, UDP
- 网络层: 源主机到目的主机的数据分组路由与转发
- IP协议、路由协议等
- 链路层: 相邻网络元素(主机、交换机、路由器等)的数据传输
- 以太网(Ethernet)、802.11 (WiFi)、PPP
- 物理层:比特传输
网络应用
体系结构
- 客户机/服务器结构(Client-Server,C/S)
- 点对点结构(Peer-to-Peer,P2P)
- 混合结构(Hybrid)
C/S结构
服务器
- 7*24小时提供服务
- 永久性访问地址/域名
- 利用大量服务器实现可扩展性(例如并发控制,大批量的请求处理)
客户机
- 与服务器通信,使用服务器提供的服务
- 间歇性接入网络
- 可能使用动态IP地址
- 不会与其他客户机直接通信
P2P结构
- 没有永远在线的服务器
- 任意端系统/节点之间可以直接通讯
- 节点间歇性接入网络
- 节点可能改变IP地址
- 优点:高度可伸缩
- 缺点:难于管理
混合结构
将C/S结构和P2P结构混合使用,成功示例:Napster
进程通信
进程间通信是网络应用的基础
进程:主机上运行的程序
同一主机上运行的进程之间的通信?
- 进程间通信机制(操作系统提供)
不同主机上运行的进程间如何通信?
- 消息交换
客户机进程: 发起通信的进程
服务器进程: 等待通信请求的进程
套接字
套接字:Socket(操作系统封装好的API)
进程间通信利用socket发送/接收消息实现
传输基础设施向进程提供API
- 传输协议的选择
- 参数的设置
寻址进程
不同主机上的进程间通信,那么每个进程必须拥有标识符
寻址主机?——IP地址,但一个主机可能同时有多个进程需要通信,所以还要端口号
进程标识符:IP地址+端口号,如 192.168.0.100:499225
端口号/Port number
- 为主机上每个需要通信的进程分配一个端口号
- 一些约定俗成的端口:HTTP Server:80,Mail Server:25
应用层协议
网络应用需遵循应用层协议(但要遵循的不只是应用层协议)
公开协议
- 由RFC(Request For Comments)定义(一般要看一个协议的详细内容可以上RFC官网查看)
- 允许互操作
- HTTP, SMTP, ……
- 私有协议
- 多数P2P文件共享应用
协议内容:
- 消息类型(type)
- 请求消息
- 响应消息
- 消息的语法(syntax)/ 格式
- 消息包含哪些字段(field)
- 每个字段如何描述
- 字段的语义(semantics)
- 字段中信息的含义
- 规则(rules)
- 进程何时发送/响应消息
- 进程如何发送/响应消息
对传输服务的需求
- 数据丢失(data loss)/ 可靠性(reliability)
- 某些网络应用能够容忍一定的数据丢失:网络电话
- 某些网络应用要求100%可靠的数据传输:文件传输,telnet
- 时间(timing)/ 延迟(delay)
- 有些应用只有在延迟足够低时才“有效”:网络电话/网络游戏
- 带宽(bandwidth)
- 某些应用只有在带宽达到最低要求时才“有效”:网络视频
- 某些应用能够适应任何带宽——弹性应用:email
Internet提供的传输服务
1、TCP服务
- 面向连接:客户机/服务器进程间需要建立连接
- 可靠的传输
- 流量控制:发送方不会发送速度过快,超过接收方的处理能力
- 拥塞控制:当网络负载过重时能够限制发送方的发送速度
- 不提供时间/延迟保障
- 不提供最小带宽保障
2、UDP服务
- 无连接
- 不可靠的数据传输
- 不提供:
- 可靠性保障
- 流量控制
- 拥塞控制
- 延迟保障
- 带宽保障
Web应用
万维网(World Wide Web):www
Web构成:1)网页 2)网页互相链接
网页(Web Page)包含多个对象(objects)
- 对象:HTML文件、JPEG图片、视频文件、动态脚本等
- 基本HTML文件:包含对其它对象引用的链接
对象的寻址(addressing)
- URL(Uniform Resoure Locator):统一资源定位器 RFC1738
- url格式:Scheme(协议)://host:port(主机IP或域名)/path
HTTP
超文本传输协议HTTP:HyperText Transfer Protocol
- 1.0版本:RFC 1945
- 2.0版本:RFC 2068
C/S结构
- 客户—Browser:请求、接收、展示Web对象
- 服务器—Web Server:响应客户的请求,发送对象
Web遵循HTTP协议——HTTP协议使用TCP传输服务
- 服务器在80端口等待客户的请求
- 浏览器发起到服务器的TCP连接(创建套接字Socket)
- 服务器接受来自浏览器的TCP连接
- 浏览器(HTTP客户端)与Web服务器(HTTP服务器)交换HTTP消息
- 关闭TCP连接
HTTP是无状态(stateless):服务器不维护任何有关客户端过去所发请求的信息(引入了Cookie技术)
有状态的协议更复杂:需维护状态(历史信息)。如果客户或服务器失效,会产生状态的不一致,解决这种不一致代价高。
HTTP连接
HTTP连接的两种类型
- 非持久性连接(Nonpersistent HTTP)
- 持久性连接(Persistent HTTP)
1、非持久性连接(Nonpersistent HTTP)
- 每个TCP连接最多允许传输一个对象
- HTTP 1.0版本使用非持久性连接
响应时间分析:
RTT(Round Trip Time):从客户端发送一个很小的数据包到服务器并返回所经历的时间
响应时间(Response time):
- 发起、建立TCP连接:1个RTT
- 发送HTTP请求消息到HTTP响应消息的前几个字节到达:1个RTT
- 响应消息中所含的文件/对象传输时间
- Total=2RTT +文件发送时间
非持久性连接的问题:
- 每个对象需要2个RTT
- 操作系统需要为每个TCP连接开销资源(overhead)
- 浏览器会打开多个并行的TCP连接以获取网页所需对象,增大了服务器的负担
2、持久性连接(Persistent HTTP)
- 每个TCP连接允许传输多个对象
- HTTP 1.1版本默认使用持久性连接
持久性连接:
- 发送响应后,服务器保持TCP连接的打开
- 后续的HTTP消息可以通过这个连接发送
分为:无流水(pipelining)的持久性连接、带有流水机制的持久性连接
无流水(pipelining)的持久性连接
- 客户端只有收到前一个响应后才发送新的请求
- 每个被引用的对象耗时1个RTT
带有流水机制的持久性连接:
- HTTP 1.1的默认选项
- 客户端只要遇到一个引用对象就尽快发出请求
- 理想情况下,收到所有的引用对象只需耗时约1个RTT
HTTP的消息格式
HTTP协议有两类消息:
- 请求消息(requests):ASCII 人直接可读
- 响应消息(response)
上传输入的方法:
POST方法:在请求消息的消息体(entity body)中上传客户端的输入
URL方法或GET方法:输入信息通过request行的URL字段上传
方法的类型:
HTTP/1.0:GET,POST,HEAD(请Server不要将所请求的对象放入响应消息中)
HTTP/1.1:GET,POST,HEAD,PUT(将消息体中的文件上传到URL字段所指定的路径),DELETE(删除URL字段所指定的文件)
响应状态代码
200 OK
301 Moved Permanently
400 Bad Request
404 Not Found
505 HTTP Version Not Supported
Cookie技术
HTTP协议无状态,很多应用需要服务器掌握客户端的状态,如网上购物。
Cookie技术 RFC6265
某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。
Cookie的组件:
- HTTP响应消息的cookie头部行
- HTTP请求消息的cookie头部行
- 保存在客户端主机上的cookie文件,由浏览器管理
- Web服务器端的后台数据库
Cookie原理:
Cookie作用:身份认证、购物车
缺点:会导致隐私问题
Web缓存/代理服务器技术
功能:在不访问服务器的前提下满足客户端的HTTP请求
作用:
- 缩短客户请求的响应时间
- 减少机构/组织的流量
- 在大范围内(Internet)实现有效的内容分发
Web缓存/代理服务器:一般由ISP(Internet服务提供商)架设
- 用户设定浏览器通过缓存进行Web访问
- 浏览器向缓存/代理服务器发送所有的HTTP请求
- 如果所请求对象在缓存中,缓存返回对象
- 否则,缓存服务器向原始服务器发送HTTP请求,获取对象,然后返回给客户端并保存该对象
- 缓存既充当客户端,也充当服务器
示例:
Web缓存/代理服务器技术需要解决的问题——如果原服务器的内容进行了更新modified,怎么保障缓存/代理服务器中的内容也是最新版本:条件性GET方法
- 目标:如果缓存有最新的版本,则不需要发送请求对象
- 缓存:在HTTP请求消息中声明所持有版本的日期
If-modified-since: <date>
- 服务器:如果缓存的版本是最新的,则响应消息中不包含对象
HTTP/1.0 304 Not Modified
Email应用
Email应用的构成组件
- 邮件客户端(user agent)
- 邮件服务器
- SMTP协议(Simple Mail Transfer Protocol)
邮件客户端:
- 读、写Email消息
- 与服务器交互,收、发Email消息
- Outlook, Foxmail, Thunderbird
- Web客户端
邮件服务器(Mail Server)
- 邮箱:存储发给该用户的Email
- 消息队列(message queue):存储等待发送的Email
SMTP协议:邮件服务器之间传递消息所使用的协议
- 客户端:发送消息的服务器
- 服务器:接收消息的服务器
SMTP协议
RFC 2821
- 使用TCP进行email消息的可靠传输,使用持久性连接
- 端口25
- 传输过程的三个阶段
- 握手
- 消息的传输
- 关闭
- 命令/响应交互模式
- 命令(command): ASCII文本
- 响应(response): 状态代码和语句
- Email消息只能包含7位ASCII码(所以邮件附件发送是用来什么技术呢?多媒体扩展)
- SMTP服务器利用CRLF.CRLF确定消息的结束
1 | # 交互示例 s-server c-client |
使用telnet与SMTP交互
telnet servername 25
- 命令:是有顺序的
HELO
MAIL FROM
RCPT TO
DATA
QUIT
与HTTP对比
- HTTP: 拉式(pull)
- SMTP: 退式(push)
- 都使用命令/响应交互模式
- 命令和状态代码都是ASCII码
- HTTP: 每个对象封装在独立的响应消息中
- SMTP: 多个对象在由多个部分构成的消息中发送
Email消息格式
多媒体扩展
MIME:多媒体邮件扩展 RFC 2045, 2056
- 通过在邮件头部增加额外的行以声明MIME的内容类型
- 实现除ASCII文本之外,图片音频等文件的发送(通过base64)
邮件访问协议
邮件访问协议:从服务器获取邮件
- POP:Post Office Protocol [RFC 1939]
- 认证/授权(客户端——服务器)和下载
- IMAP:Internet Mail Access Protocol [RFC 1730]
- 更多功能
- 更加复杂
- 能够操纵服务器上存储的消息
- HTTP:163, QQ Mail等
POP协议
“下载并删除”模式
- 用户如果换了客户端软件,无法重读该邮件
“下载并保持”模式:不同客户端都可以保留消息的拷贝
POP3是无状态的
IMAP协议
所有消息统一保存在一个地方:服务器
允许用户利用文件夹组织消息
IMAP支持跨会话(Session)的用户状态:
- 文件夹的名字
- 文件夹与消息ID之间的映射等
DNS应用
DNS:Domain Name System
Internet上主机/路由器的识别
- IP地址 192.168.0.1
- 域名:www.hit.edu.cn
- IP和域名之间存在映射关系,域名的优点是容易记
域名解析系统DNS:
- 多层命名服务器构成的分布式数据库
- 应用层协议:完成名字的解析
- Internet核心功能,用应用层协议实现
- 网络边界复杂
DNS服务:
- 域名向IP地址的翻译
- 主机别名
- 邮件服务器别名
- 负载均衡:Web服务器
为什么不使用集中式的DNS?
- 单点失败问题
- 流量问题
- 距离问题
- 维护性问题
DNS结构
分布式层次式数据库
示例:客户端想要查询www.amazon.com的IP
- 客户端查询根服务器,找到com域名解析服务器
- 客户端查询com域名解析服务器,找到amazon.com域名解析服务器
- 客户端查询amazon.com域名解析服务器,获得www.amazon.com的IP地址
域名服务器类型
DNS根域名服务器:
- 本地域名解析服务器无法解析域名时,访问根域名服务器
- 根域名服务器
- 如果不知道映射,访问权威域名服务器
- 获得映射
- 向本地域名服务器返回映射
顶级域名服务器(TLD, top-level domain):负责com, org, net,edu等顶级域名和国家顶级域名,例如cn, uk, fr等
- Network Solutions维护com顶级域名服务器
- Educause维护edu顶级域名服务器
权威(Authoritative)域名服务器:组织的域名解析服务器,提供组织内部服务器的解析服务
- 组织负责维护
- 服务提供商负责维护
本地域名解析服务器:
- 不严格属于层级体系
- 每个ISP有一个本地域名服务器,默认域名解析服务器
- 当主机进行DNS查询时,查询被发送到本地域名服务器,作为代理(proxy),将查询转发给(层级式)域名解析服务器系统
DNS查询
DNS查询示例:Cis.poly.edu 的主机想获得 gaia.cs.umass.edu的IP地址
1、迭代查询
- 被查询服务器返回域名解析服务器的名字
2、递归查询
- 将域名解析的任务交给所联系的服务器
DNS缓存
DNS记录缓存和更新:
只要域名解析服务器获得域名—IP映射,即缓存这一映射
- 一段时间过后,缓存条目失效(删除)
- 本地域名服务器一般会缓存顶级域名服务器的映射,因此根域名服务器不经常被访问
记录的更新/通知机制:
- RFC 2136
- Dynamic Updates in the Domain Name System (DNS UPDATE)
DNS记录格式
资源记录(RR, resource records),RR format : (name,value,type,ttl)
- Type=A
- Name: 主机域名
- Value: IP地址
- Type=NS
- Name: 域(edu.cn)
- Value: 该域权威域名解析服务器的主机域名
- Type=CNAME
- Name: 某一真实域名的别名www.ibm.com——servereast.backup2.ibm.com
- Value: 真实域名
- Type=MX
- Value是与name相对应的邮件服务器
DNS消息格式
DNS协议:
- 查询(query)和回复(reply消息)
- 消息格式相同
消息头部
- Identification: 16位查询编号,回复使用相同的编号
- flags
- 查询或回复
- 期望递归
- 递归可用
- 权威回答
域名注册
P2P应用
客户机/服务器:
P2P:
BitTorrent(BT)
- 文件划分为256KB的chunk
- 节点加入torrent
- 没有chunk,但是会逐渐积累
- 向tracker注册以获得节点清单,与某些节点(“邻居”)建立连接
- 下载的同时,节点需要向其他节点上传chunk
- 节点可能加入或离开
- 一旦节点获得完整的文件,它可能(自私地)离开或(无私地)留下
- 获取chunk
- 给定任一时刻,不同的节点持有文件的不同chunk集合
- 节点(Alice)定期查询每个邻居所持有的chunk列表
- 节点发送请求,请求获取缺失的chunk——稀缺优先
- 发送chunk:tit-for-tat
- Alice向4个邻居发送chunk:正在向其发送Chunk,速率最快的4个
- 每10秒重新评估top 4
- 每30秒随机选择一个其他节点,向其发送chunk
- 新选择节点可能加入top 4
- “optimistically unchoke”
- Alice向4个邻居发送chunk:正在向其发送Chunk,速率最快的4个
BT的危害:
- 传播盗版
- 损害硬盘
- 传播病毒
- 损害宽带
索引技术
P2P系统的索引:信息到节点位置(IP地址+端口号)的映射
- 文件共享(电驴)
- 利用索引动态跟踪节点所共享的文件的位置
- 节点需要告诉索引它拥有哪些文件
- 节点搜索索引,从而获知能够得到哪些文件
- 即时消息(QQ)
- 索引负责将用户名映射到位置
- 当用户开启IM应用时,需要通知索引它的位置
- 节点检索索引,确定用户的IP地址
集中式索引
Napster最早采用这种设计
- 节点加入时,通知中央服务器:IP地址、内容
- Alice查找“Hey Jude”
- Alice从Bob处请求文件
问题:
- 单点失效问题
- 性能瓶颈
- 版权问题
洪泛式查询
洪泛式Query flooding:完全分布式架构,Gnutella采用这种架构
- 每个节点对它共享的文件进行索引,且只对它共享的文件
覆盖网络(overlay network): Graph
- 节点X与Y之间如果有TCP连接,那么构成一个边
- 所有的活动节点和边构成覆盖网络
- 边:虚拟链路
- 节点一般邻居数少于10个
查询消息通过已有的TCP连接发送
节点转发查询消息
如果查询命中,则利用反向路径发回查询节点
层次式覆盖网络
- 介于集中式索引和洪泛查询之间的方法
- 每个节点或者是一个超级节点,或者被分配一个超级节点
- 节点和超级节点间维持TCP连接
- 某些超级节点对之间维持TCP连接
- 超级节点负责跟踪子节点的内容
应用案例:Skype
Socket编程
应用编程接口API(Application Programming Interface)
- 就是应用进程的控制权和操作系统的控制权进行转换的一个系统调用接口。
几种典型的应用编程接口
- Berkeley UNIX 操作系统定义了一种 API,称为套接字接口(socket interface),简称套接字(socket)。
- 微软公司在其操作系统中采用了套接字接口 API,形成了一个稍有不同的 API,并称之为
Windows Socket Interface,WINSOCK。 - AT&T 为其 UNIX 系统 V 定义了一种 API,简写为 TLI(Transport Layer Interface)
Socket API
最初设计
- 面向BSD UNIX-Berkley
- 面向TCP/IP协议栈接口
目前
- 事实上的工业标准
- 绝大多数操作系统都支持
Internet网络应用最典型的API接口
通信模型:客户/服务器(C/S)
是应用进程间通信的抽象机制
标识通信端点(对外):IP地址+端口号
操作系统/进程如何管理套接字(对内):套接字描述符(socket descriptor),是一个小整数
当应用进程创建套接字时,操作系统分配一个数据结构存储该套接字相关信息,返回套接字描述符。
地址结构:
已定义结构sockaddr_in:
1 | struct sockaddr_in |
使用TCP/IP协议簇的网络应用程序声明端点地址变量时,使用结构sockaddr_in
Socket API函数
1、WSAStartup:int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
使用Socket的应用程序在使用Socket之前必须首先调用WSAStartup函数
- 第一个参数指明程序请求使用的WinSock版本,其中高位字节指明副版本、低位字节指明主版本.
- 十六进制整数,例如0x102表示2.1版
- 第二个参数返回实际的WinSock的版本信息,指向WSADATA结构的指针
例:使用2.1版本的WinSock的程序代码段
1 | wVersionRequested = MAKEWORD( 2, 1 ); |
2、WSACleanup:int WSACleanup (void);
应用程序在完成对请求的Socket库的使用, 最后要调用WSACleanup函数,解除与Socket库的绑定,释放Socket库所占用的系统资源
3、socket:sd = socket(protofamily,type,proto);
创建套接字,操作系统返回套接字描述符(sd)
- 第一个参数(协议族):protofamily = PF_INET(TCP/IP)
- 第二个参数(套接字类型):
- type = SOCK_STREAM, SOCK_DGRAM or SOCK_RAW(TCP/IP)
- 第三个参数(协议号):0为默认
例:创建一个流套接字的代码段
1 | struct protoent *p; |
Socket面向TCP/IP的服务类型:
- TCP:可靠、面向连接、字节流传输、点对点
- UDP:不可靠、无连接、数据报传输
4、closesocket:int closesocket(SOCKET sd);
关闭一个描述符为sd的套接字
如果多个进程共享一个套接字,调用closesocket,将套接字引用计数减1,减至0才关闭
一个进程中的多线程对一个套接字的使用无计数。即如果进程中的一个线程调用closesocket将一个套接字关闭,该进程中的其他线程也将不能访问该套接字
返回值:0:成功、SOCKET_ERROR:失败
5、bind:int bind(sd,localaddr,addrlen);
绑定套接字的本地端点地址:IP地址+端口号
参数:
- 套接字描述符(sd)
- 端点地址(localaddr)结构sockaddr_in
客户程序一般不必调用bind函数,服务器端一般必要
例:如下情形两个IP接入
解决方案——地址通配符:INADDR_ANY
6、listen:int listen(sd, queuesize);
置服务器端的流套接字处于监听状态
- 仅服务器端调用
- 仅用于面向连接的流套接字
设置连接请求队列大小(queuesize)
返回值:0:成功 SOCKET_ERROR:失败
7、connect:connect(sd, saddr, saddrlen);
客户程序调用connect函数来使客户套接字(sd)与特定计算机的特定端口(saddr)的套接字(服务)进行连接
仅用于客户端
可用于TCP客户端也可以用于UDP客户端
- TCP客户端:建立TCP连接
- UDP客户端:指定服务器端点地址
8、accept:newsock = accept(sd, caddr, caddrlen);
服务程序调用accept函数从处于监听状态的流套接字sd的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道
- 仅用于TCP套接字
- 仅用于服务器
利用新创建的套接字(newsock)与客户通信
9、send:send(sd, *buf, len, flags);
send函数用于TCP套接字(客户与服务器)或调用了connect函数的UDP客户端套接字
10、sendto:sendto(sd, *buf, len, flags, destaddr, addrlen);
sendto函数用于UDP服务器端套接字与未调用connect函数的UDP客户端套接字
11、recv:recv(sd, *buffer, len, flags);
recv函数从TCP连接的另一端接收数据,或者从调用了connect函数的UDP客户端套接字接收服务器发来的数据。
12、recvfrom:recvfrom(sd, *buf, len, flags, senderaddr, saddrlen);
recvfrom函数用于从UDP服务器端套接字与未调用connect函数的UDP客户端套接字接收对端数据
13、setsockopt:int setsockopt(int sd, int level, int optname, *optval, int optlen);
setsockopt()函数用来设置套接字sd的选项参数
14、getsockopt:int getsockopt(int sd, int level, int optname, *optval, socklen_t *optlen);
getsockopt()函数用于获取任意类型、任意状态套接口的选项当前值,并把结果存入optval
API函数小结
WSAStartup:初始化socket库(仅对WinSock)
WSACleanup:清楚/终止socket库的使用 (仅对WinSock)
socket:创建套接字
connect:“连接”远端服务器 (仅用于客户端)
closesocket:释放/关闭套接字
bind:绑定套接字的本地IP地址和端口号(通常客户端不需要)
listen:置服务器端TCP套接字为监听模式,并设置队列大小 (仅用于服务器端TCP套接字)
accept:接受/提取一个连接请求,创建新套接字,通过新套接 (仅用于服务器端的TCP套接字)
recv:接收数据(用于TCP套接字或连接模式的客户端UDP套接字)
recvfrom:接收数据报(用于非连接模式的UDP套接字)
send:发送数据(用于TCP套接字或连接模式的客户端UDP套接字)
sendto:发送数据报(用于非连接模式的UDP套接字)
setsockopt:设置套接字选项参数
getsockopt:获取套接字选项参数
网络字节顺序
TCP/IP定义了标准的用于协议头中的二进制整数表示:网络字节顺序(network byte order)
某些Socket API函数的参数需要存储为网络字节顺序(如IP地址、端口号等)
可以实现本地字节顺序与网络字节顺序间转换的函数
- htons:本地字节顺序→网络字节顺序(16bits)
- ntohs:网络字节顺序→本地字节顺序(16bits)
- htonl:本地字节顺序→网络字节顺序(32bits)
- ntohl:网络字节顺序→本地字节顺序(32bits)
解析IP地址
客户端可能使用域名(如:study.163.com)或IP地址(如:123.58.180.121)标识服务器
IP协议需要使用32位二进制IP地址,需要将域名或IP地址转换为32位IP地址
函数inet_addr()
实现点分十进制IP地址到32位IP地址转换
函数gethostbyname()
实现域名到32位IP地址转换,返回一个指向结构hostent
的指针
1 | struct hostent { |
解析端口号
客户端还可能使用服务名(如HTTP)标识服务器端口,需要将服务名转换为熟知端口号
函数getservbyname( )
,返回一个指向结构servent
的指针
1 | struct servent { |
解析协议号
客户端可能使用协议名(如:TCP)指定协议,需要将协议名转换为协议号(如:6)
函数getprotobyname()
实现协议名到协议号的转换,返回一个指向结构protoent
的指针
1 | struct protoent { |
客户端软件流程
TCP:
确定服务器IP地址与端口号
创建套接字
- 分配本地端点地址(IP地址+端口号)
- 连接服务器(套接字)
- 遵循应用层协议进行通信
- 关闭/释放连接
UDP:
- 确定服务器IP地址与端口号
- 创建套接字
- 分配本地端点地址(IP地址+端口号)
- 指定服务器端点地址,构造UDP数据报
- 遵循应用层协议进行通信
- 关闭/释放套接字
服务器基本流程
4种类型基本服务器
- 循环无连接(Iterative connectionless)服务器
- 循环面向连接(Iterative connection-oriented)服务器
- 并发无连接(Concurrent connectionless)服务器
- 并发面向连接(Concurrent connection-oriented)服务器
循环无连接服务器
- 创建套接字
- 绑定端点地址(INADDR_ANY+端口号)
- 反复接收来自客户端的请求
- 遵循应用层协议,构造响应报文,发送客户
循环面向连接服务器
- 创建(主)套接字,并绑定熟知端口号;
- 设置(主)套接字为被动监听模式,准备用于服务器;
- 调用accept()函数接收下一个连接请求(通过主套接字),创建新套接字用于与该客户建立
连接; - 遵循应用层协议,反复接收客户请求,构造并发送响应(通过新套接字);
- 完成为特定客户服务后,关闭与该客户之间的连接,返回步骤3
并发无连接服务器:
主线程第一步:创建套接字,并绑定熟知端口号;
主线程第二步:反复调用recvfrom()函数,接收下一个客户请求,并创建新线程处理该客户响
应;
子线程第一步:接收一个特定请求;
子线程第二步:依据应用层协议构造响应报文,并调用sendto()发送;
子线程第三步:退出(一个子线程处理一个请求后即终止)
并发面向连接服务器
主线程第一步:创建(主)套接字,并绑定熟知端口号;
主线程第二步:设置(主)套接字为被动监听模式,准备用于服务器;
主线程第三步:反复调用accept()函数接收下一个连接请求(通过主套接字),并创建一个新
的子线程处理该客户响应;
子线程第一步:接收一个客户的服务请求(通过新创建的套接字);
子线程第二步:遵循应用层协议与特定客户进行交互;
子线程第三步:关闭/释放连接并退出(线程终止)
数据发送:
服务器端不能使用connect()函数
无连接服务器使用sendto()函数发送数据报
调用recvfrom()函数接收数据时,自动提取客户端点地址