· 应用层协议原理:
· · 应用程序体系结构:
· · 主要有客户—服务器体系结构、对等体系结构。由应用程序研发者设计。
· · · 客户—服务器(C/S)体系结构:
· · · 服务器是一直运行的、拥有固定IP地址和周知的端口号、可扩展性。
· · · 客户端主动与服务器通信、与互联网有间歇性的连接、可能是动态的IP地址,客户端之间不能直接通信。
· · · P2P(对等)体系结构:
· · · 服务器不是一直运行的,任何端系统可以直接通信,任何一个节点既是服务器也是客户端、拥有自扩展性,参与主机的间歇性连接还可以改变IP地址,但是难以管理。
· · · C/S和P2P结构体系的混合:
例如:
· · · Napste
· · · · 文件搜索:集中性。主机在中心服务器上注册其资源,主机向中心服务器查询资源。
· · · · 文件传输:P2P,任意节点之间传输。
· · · 及时通信
· · · · 在线检测:集中性。当用户上线时,向中心服务器注册其IP地址,然后与中心服务器联系,找到其它用户所处位置。
· · · · 两个用户之间的聊天:P2P。
· · 进程通信:
· · 在两个不同端系统上的进程,通过跨越计算机网络交换报文,实现相互通信。
· · · 客户与服务器进程:
· · · 在一对进程之间的通信会话中,发起通信的进程标识为客户,在会话开始时等待联系的进程是服务器。
· · · 进程与计算机网络接口:
· · · 进程通过一个被称为 套接字(socket) 的软件接口向网络发送报文和接收报文。套接字就像一个门户,进程只需要将报文推出套接字,然后报文经过一系列的传输,最终到达接收进程的套接字,随后被进程处理。
· · · 套接字是一台主机内应用层与运输层之间的接口,而且是建立网络应用程序的可编程接口,因此套接字也叫做应用程序与网络之间的 应用程序编程接口(API)。
· · · 应用程序开发者可以控制选择运输层协议(TCP、UDP)。还能设定几个运输层参数(最大缓存、最大报文段长度等)。
· · · 分布式进程通信需要解决的问题:
· · · · (1)进程标识和寻址问题:
· · · · 进程为了接收和发送报文必须要有一个标识,即SAP。由目的进程通过特定的套接字(socket)发送报文,套接字(socket)中包含了传送地址。
· · · · · IP地址:
· · · · · 用来标识主机,是一个32bit的值。
· · · · · 端口(port)号:
· · · · · 一般来说,一个主机上可以运行多个应用程序,而端口号就是分配给每个应用程序特定的地址的编号,使进程发送的报文顺利到达目的进程。
· · · · · 目前流行的应用程序有特定的端口号:
Web服务器——端口号80
邮件服务器进程(SMTP协议)——端口号25
· · · · (2)传输层提供的服务-层间信息的代表:
· · · · TCP socket:
· · · · · TCP服务,两个进程之间的通信需要之前要建立连接。两个进程通信会持续一段时间,通信关系稳定。
· · · · · 可以用一个整数表示两个应用实体之间的通信关系,为了使本地标示穿过层间接口的信息量最小。
· · · · · TCP socket:源IP,源端口,目标IP,目标端口。用于指明应用进程会话的本地标识。位于应用层与传输层的接口界面上。
· · · · · 代表一个四元组,表示了两个进程之间的会话关系。就不必在每一个报文的发送都要指定这个4元组。简单且便于管理。
· · · · UDP socket:
· · · · · 提供UDP服务,两个进程之间的通信需要之前无需建立连接,每个报文都是独立传输的,前后报文可能给不同的分布式进程,因此,只能用一个整数表示本应用实体的标示,因为这个报文可能传给另外一个分布式进程。
· · · · · 可以用一个整数表示两个应用实体之间的通信关系,为了使穿过层间接口的信息大小最小。
· · · · · UDP socket:本主机的IP,本主机的端口。但是传输报文时,必须要提供对方IP,port。因为在目的主机接收报文时,传输层需要上传源主机的IP,port。
· · · · · 对于使用无连接服务(UDP)的应用而言,套接字是2元组的一个具有本地意义的标示2元组:IP,port (源端指定)UDP套接字指定了应用所在的一个端节点(end point)。
· · · · · 在发送数据报时,采用创建好的本地套接字(标示ID),就不必在发送每个报文中指明自己所采用的ip和port。但是在发送报文时,必须要指定对方的ip和port(另外一个端节点)。
· · · · 总之,在发送报文时,报文必须具备源主机的IP和port、目的主机的IP和port以及传输的数据。
· · · · 如何使用运输层提供的服务实现应用:
· · · · 定义应用层协议:报文格式,解释,时序等。
· · · · 编制程序,通过API调用网络基础设施提供通信服务,如传报文,解析报文,实现应用时序等。
· · · 由应用程序使用的运输服务:
· · · 当开发一个应用程序时必须规定一种可用的运输层协议(TCP、UDP),每个运输层协议有可靠数据传输、吞吐量、定时和安全性等性能。
· · · · 可靠数据传输:
· · · · 一些协议可以将数据正确、完整、不乱序的交付给目的进程。这样的协议就具有可靠数据传输性,如TCP协议,被一些通信软件或者银行等应用程序软件所采纳。
· · · · 此外还有协议在传输数据时,可能会丢弃一些数据,不可靠,这样的协议就不具备可靠数据传输,如UDP协议,由于多媒体应用可以承受一定的数据丢失,所以一些多媒体应用采取UDP协议。
· · · · 吞吐量:
· · · · 有些运输层协议能够以特定的速率提供确保的可用吞吐量。由于应用程序需要对数据以一定的吞吐量发送,但是由于链路、协议等问题,达不到应用程序的吞吐量,可能会导致应用程序以低速率进行编码(较低吞吐量)、或者直接放弃发送,所以效率很低,或根本没用。这种应用程序被认为是带宽敏感的应用,具有特定的吞吐量。而弹性应用可以根据情况确定吞吐量(如:电子邮件、文件传输、web传送等)。
· · · · 一些协议可以良好的控制吞吐量,但也有可能因为链路问题导致吞吐量过低,使应用程序放弃发送数据。
· · · · 定时:
· · · · 运输层协议也能提供定时保证,如发送方注入套接字的每个bit到达接收方的套接字不迟于100ms。这种保证对实时应用影响很大(如视频、语言通话、游戏等)
· · · · 安全性:
运输层协议能为应用程序提供多种安全性服务,例如在发送中,运输协议可以加密发送进程传输的所有数据,也可以在接收进程之前解密数据。
· · · 因特网提供的运输服务
因特网提供了TCP和UDP协议。
· · · · TCP服务:
· · · · (1)面向连接的服务:在客户与服务器之间发送数据时必须提前在两个进程套接字之间建立连接(交换运输层控制信息)。
· · · · (2)可靠的数据传送服务:进程依靠TCP可以无差错、按顺序地交付所有发送数据,没有字节的丢失和冗余。
· · · · (3)拥塞控制机制:当发送方和接收方之间的网络出现拥塞时,这个机制会抑制发送进程,或者限制每个TCP连接。
· · · · (4)无安全性,没有提供加密机制。(最新的SSL(安全套接字层,Secure Sockets Layer)是TCP的加强版,可以提供数据加密)。
· · · · UDP服务:
· · · · 它是一种不提供不必要服务的轻量级运输协议,是一种无连接服务、不可靠数据传输服务、无拥塞控制机制。
· · · · 一些常见应用支持的服务:
· · · 应用层协议:
· · · · 定义了运行在不同端系统上的应用程序进程如何相互传递报文。主要定义了:
交换的报文类型,如请求报文和响应报文。
各种报文类型的语法。
字段的语义。
一个进程何时以及如何发送报文,对报文进行响应的规则。
· · · · 有些应用层协议是由RFC文档定义的,因此位于公共域中,如Web的应用层协议HTTP(超文本传输协议)就作为一个RFC使用。还有些应用层协议是专用的,不被公共域使用。
· · · · HTTP、FTP、SMTP/POP3/IMAP、DNS
· · · · 应用层协议是网络应用的一部分。
· · · · 如Web是一种客户—服务器应用,包含了文档格式HTML、Web浏览器、Web服务器,以及一个应用层协议(HTTP定义了Web服务器和浏览器之间传输的报文格式和序列)。
· · · · 还比如因特网电子邮件应用,包含了容纳用户邮箱的邮件服务器、允许用户读取和生成邮件的邮件客户程序,应用层协议( SMTP(简单邮件传输协议) 定义了电子邮件报文结构的标准、定义了如何在服务器之间以及如何在服务器与邮件客户程序之间传递、定义了如何对报文首部的内容进行解释)。
· Web和HTTP
· · 一些常用术语:
· Web页:有一些对象组成,对象可以是HTML文件、JPEG图像、Java小程序、声音剪辑文件等。
· Web页含有一个基础的HTML文件,该基本HTML文件又包含许多对象的引用(链接)
· 通过URL对每个对象进行引用(访问协议、用户名、端口、口令字等)
· URL格式:协议名 + 用户 + 口令 + 主机名 + 路径名 + 端口(其中用户名和主机名可以省略,即为默认)。
· · HTTP概述:
· · HTTP协议(超文本传输协议)是Web的应用协议。
· · Web浏览器实现了HTTP的客户端,Web服务器实现了HTTP的服务器端,用于储存Web对象,每个对象都由URL寻址。
· · HTTP定义了Web客户向Web服务器请求Web页面的方式,以及服务器向客户传送Web页面的方式。
· · · 持久与非持久HTTP
· · · 非持久HTTP:最多有一个对象在TCP上连接发送,下载多个对象需要建立多个连接,如HTTP/1.0使用非持久连接。
· · · 持久HTTP:多个对象可以在一个(在客户端和服务器之间的)TCP连接上传输,如HTTP/1.1使用持久连接。
· · · 响应时间模型:
· · · · 往返时间RTT(round-trip time):一个分组从客户端到服务器,再回到客户端的时间(传输时间省略不计)。
· · · ·响应时间:2RTT+传输时间,一个RTT用来发起TCP连接,一个RTT用来HTTP请求并等待HTTP响应,再加上文件传输时间。
· · · · 非持久HTTP连接:
· · · · 首先HTTP客户端在端口号80(HTTP默认端口)发起一个到目的HTTP服务器的连接。
· · · · 目的HTTP服务器在80号端口等待连接,接受连接并通知客户端。
· · · · HTTP客户端向TCP连接的套接字发送HTTP请求报文,报文表示客户端需要对象。
· · · · HTTP服务器接收到请求报文,从储存器中检索出被请求的对象,将对象封装在一个响应报文,并通过其套接字象客户端发送。
· · · · HTTP服务器进程通知TCP断开该TCP连接(直到TCP确认客户已经完整地收到响应报文为止,它才会实际的断开连接)。
· · · · HTTP客户端收到包含html文件的响应报文,关闭TCP连接,并显示html。然后对html文件进行检查,如果找到了多个引用对象需要请求资源,则对那几个对象,重复前几步,请求资源。
· · · · 注意,因为TCP是可靠传输协议,所以HTTP不需要关注报文能否传输完全,都是由其它层次所实现。HTTP是无状态的,服务器不能维护关于客户的任何信息。HTTP仅定义了在HTTP客户程序与HTTP服务器之间的通信协议
· · · · 非持久HTTP的缺点:每个对象需要两个RTT,操作系统必须为每个TCP连接分配资源。但浏览器通常打开并进行TCP连接,以获取引用连接。
· · · · 持久HTTP连接:
· · · · 服务器在发送响应后,仍保持TCP连接,在相同客户端和服务器之间的后续请求和响应报文,通过相同的连接进行传送,客户端在遇到一个引用对象的时候,就可以尽快发送该对象的请求。
· · · · 非流水方式的持久HTTP:客户端只能在收到前一个响应之后才能发出新的请求,每个引用对象花费一个RTT。
· · · · 流水方式的持久HTTP:是HTTP/1.1的默认模式,客户端遇到一个引用对象就立即产生一个请求。所有的引用对象可能只花费一个RTT时间。
· · · HTTP报文格式:
· · · 分为请求报文和响应报文。
· · · · HTTP请求报文:
· · · · 由ASCII码组成(人能阅读的)。每一行最后都有一个回车和换行符结束,最后一行再附加一个回车换行符。
· · · · HTTP请求报文第一行为请求行,后面的行叫做首部行。
· · · · 请求行有三个字段:方法字段、URL字段和HTTP版本字段。方法字段可以取的值有:GET、POST、HAED、PUT和DELETE。大部分使用GET方法。在GET方法中,在URL字段带有请求对象的标识。
· · · · Host首部行指明了对象所在的主机,这条信息是Web代理高速缓存所要求的。
· · · · Connection首部行表示该浏览器告诉服务器不想使用持续连接,要求服务器在发送被请求对象之后就关闭这条连接。
· · · · User-agent首部行用来指明用户代理,即向服务器发送请求的浏览器的类型(通过这条信息,服务器可以有效的为不同类型的用户代理发送相同对象的不同版本)。
· · · · Accept-language首部行表示用户想要得到该对象的语法版本,否则服务器发送它的默认版本。
· · · · 在首部行(和附加的换行和回车)之后有一个‘实体体’。使用GET方法时实体体为空,使用POST方法时才使用实体体。
当用户提交表单时,HTTP客户一般使用
POST方法,例如在用户向搜索引擎提供搜索
关键字时,使用POST报文时,用户依然可以
向服务器请求一个Web页面,但Web页面的特
定内容和用户在表单字段中输入的内容有关,
此时的实体体包含这个输入值。
注意用表单生成的请求报文不是必须使用
POST方法的,HTML表单经常使用GET方法,
并在(表单字段中)请求的URL中输入的数据。
HEAD方法类似于GET方法,在服务器收到
HEAD方法的请求时,会用HTTP报文响应,
但不返回请求对象。
PUT方法允许用户上传对象到指定的Web服务
器上指定的路径。常被需要向Web服务器上传
对象的应用程序使用。
DELETE方法允许用户或应用程序删除Web
服务器上的对象。
· · · · 格式:sp->空格 cr->回车 lf->换行
· · · · HTTP响应报文:
· · · · 包含初始状态行、6个首部行、实体体。实体体是报文的主要部分,包含了所请求的对象本身。
· · · · 初始状态行有3个字段:协议版本字段、状态码、相应状态信息。
常见状态码与相应状态信息
200 OK 请求成功,信息在返回的响应报文中。
301 Moved Permanently 请求的对象已经被永久的转移了,新的URL定义在响应报文的Location首部行中,客户软件将自动获取1新的URL。
304 Not Modified 告知缓存器对象并没有被修改。
400 Bad Request 一个通用的差错代码,指示请求不能被服务器理解。
404 Not Found 被请求的文档不在服务器上。
505 HTTP Version Not Supported 服务器不支持请求报文使用的HTTP协议版本。
· · · · Connection首部行告诉客户,发送完报文后将关闭TCP连接。
· · · · Date首部行指示服务器产生并发送该响应报文的日期和时间,这个时间是服务器从它的文件系统中检索到该对象,插入到响应报文,并发送该响应报文的时间。
· · · · Sever首部行指示该报文是由何种类型的服务器发送。
· · · · Last-Modified首部行对既存在于本地客户也可能存在于网络缓存服务器(代理服务器)上的对象缓存来说很重要。表示此对象最后被发送的时间。
· · · · Content-Length首部行指示了被发送对象中的字节数。
· · · · Content-Type首部行指示了实体体中的对象类型。
· · 用户与服务器的交互:cookie
· · HTTP使用cookie运行站点对用户进行跟踪、识别、限制、与内容联系起来。
· · · cookie组件:
· · · 在HTTP响应报文中有一个cookie的首部行
· · · 在HTTP请求报文含有一个cookie文件。
· · · 在用户端系统中保留有一个cookie文件,由用户的浏览器管理。
· · · 在Web站点有一个后端数据库。
· · · cookie工作原理:
· · · 当用户使用浏览器首次访问服务器站点时,该站点会产生唯一的识别码,并以此为索引在后端数据库建立一个表项。
· · · 然后服务器会用一个包含Set-cookie首部行的HTTP响应报文对浏览器进行响应。
· · · 当浏览器收到响应报文时,它会根据cookie首部行在它管理的特定cookie文件中添加一行,包含了服务器的主机名和Set-cookie首部行中的识别码。
· · · 然后用户每次请求一个Web页面时,浏览器会从该cookie文件中获得对这个网站的识别码,并放到HTTP请求报文中包括识别码的cookie首部行。
· · · 服务器站点就会根据cookie值了解用户在此站点的所有信息。
· · · cookie的危害性:
· · · 用户信息可能会被泄露。
Web缓存:
· · Web缓存器也叫做代理服务器,它可以代表初始Web服务器来满足HTTP请求的网络实体,拥有自己的缓存空间,可以储存最近请求过对象的副本。
· · · 使用Web缓存的特性:
· · · 降低客户端的请求响应时间
· · · 可以大大减少一个机构内部网络与Internet接入链路的流量
· · · 互联网大量采用了缓存,可以使较弱的ICP也能够提供内容。
· · · 它既是服务器又是客户。Web服务器通常由ISP购买并安装。
· · · 使用方法:
· · · 浏览器建立一个到Web缓存器的TCP连接,并向Web缓存器中的对象发送一个HTTP请求。
· · · Web缓存器进行检查,看看本地是否存在该对象的副本。如果有的话Web缓存器就向客户浏览器用HTTP响应报文返回该对象。
· · · 如果Web缓存器中没有该对象,它就会打开一个与该对象的初始化服务器的TCP连接。Web缓存器则在这个缓存器到服务器的TCP连接上发送一个对该对象的HTTP请求。随后初始化服务器就会给Web缓存器发送一个HTTP响应报文。
· · ·当Web缓存器收到该对象时,在本地保留一份副本,并向客户的浏览器用HTTP响应报文发送该副本。
· · 条件GET方法:
· · 虽然Web缓存器能够大幅度的降低用户向源目的服务器的请求次数,降低客户端的响应时间,降低内部机构网络与因特网接入链路的流量。但是如果Web缓存器中存放的对象是老旧的,也就是说保存在服务器上的对象可能被修改了,那么就需要用条件GET方法保证缓存器中的对象是最新的。
· · · 条件GET请求报文:
· · · 一个使用GET方法的请求报文,并且在请求报文中包含一个“If-Modified-Since”首部行。
· · ·大致使用过程:
· · · 起初,缓存器向服务器发送一个包含请求对象地址(Host首部行)的请求报文,然后服务器响应一个被请求对象的报文。此时缓存器保存了该对象的最后修改日期,当以后浏览器向缓存器请求该对象时,缓存器会先向服务器发送一个条件GET请求报文(包含了If-Modified-Since首部行,这个首部行的内容代表了上一次该对象的最后修改时间),然后Web服务器会发送一个响应报文(没有更改时,不会包含旧对象的内容),表明没有修改该对象。
· 文件传输协议(FTP)
· 用户主机向一台远程主机传输或者接收文件,用户必须提供用户标识和口令。FTP客户端与FTP服务器通过端口21联系,并使用TCP为传输协议。使用了两个并行的TCP连接来传输文件,一个是控制连接,一个是数据连接。
· · 控制连接与数据连接分开连接:
· · 控制连接用于主机间的传输控制信息,如用户标识、口令、改变远程目录的命令以及“存放”和“获取”文件的命令。
· · 数据连接用于发送一个文件。
· · 客户端通过控制连接获得身份确认。
· · 客户端通过控制连接发送命令浏览远程目录。
· · 收到一个文件传输命令时,服务器打开一个到客户端的数据连接
· · 一个文件传输完成后,服务器关闭连接。
· · FTP的一些特性:
· · 数据连接是非持续性的,也就是说会话中的每一次文件传输都会建立一个新的数据连接。
· · FTP服务器必须在整个会话期间保留用户的状态
· · 从客户端到服务器的命令和从服务器到客户端的回答,都是7bitASCII格式在控制连接上传送的。
· · 命令具有可读性,每个命令后跟回车和换行符。每个命令由四个大写的ASCII字符组成,有些具有可选参数。
· · 每一回答对应着一个命令,回答是一个三位数字,后面跟着一个可选信息。与HTTP响应报文状态行的状态码和状态信息结构相同。
· · 常见的FTP命令和回答:
· · · 命令:
· · · USER username:用于向服务器传送用户标识。
· · · PASS password:用于向服务器传送用户口令。
· · · LIST:用于请求服务器送回当前远程目录中的所有文件列表。该文件列表是由一个新建且非持续的数据连接传送的,而不是控制TCP连接上传送。
· · · RETR filename:用于从远程主机当前目录检索文件。该命令引起远程主机发起一个数据连接,并经该数据连接发送所请求的文件。
· · · STOP filename:用于在远程主机的当前目录上存放文件。
· · · 回答:
· · · 331 Username OK,Password required(用户名OK,需要口令)。
· · · 125 Data connection already open;transfer starting(数据连接已经打开,开始传送)。
· · · 425 Can’t open data connection(无法打开数据连接)。
· · · 452 Error writing file (写文件差错)。
· 因特网中的电子邮件(EMail)
· · EMail组成部分:
· · 用户代理、邮件服务器、简单邮件传输协议:SMTP。
· · 用户代理:邮件阅读器,编写、编辑和阅读邮件,输出和输入邮件保存在服务器上。
· · 邮件服务器:邮箱中管理和维护发送给用户
的邮件,输出报文队列保持待发送邮件报文。
· · SMTP协议:包含两个部分:运行在发送方邮件服务器的客户端和运行在接收方邮件服务器的服务器端。
· · SMTP协议:
· · 使用TCP在客户端和服务器之间传送报文,端口号为25。
· · 直接传输:从发送方服务器到接收方服务器传输的3个阶段,握手、传输报文、关闭。
· · 命令/响应交互:命令为ASCII文本,响应为状态码和状态信息。
· · 报文必须为7位ASCII码。
· · 使用持久连接,回车换行+.+回车换行,代表了报文的尾部。
· · 与HTTP相比较,HTTP是一种拉的形式,SMTP是推的形式。二者都是ASCII形式的命令/响应交互、状态码。HTTP的每个对象封装在自己的响应报文内,SMTP的多个对象包含在一个报文中。
· · 简单的SMTP交互与邮件传送方式:
其中红色字为命令,S所响应的是回答。
· · 邮件报文格式和MIME:
· · 报文格式
每个首部必须包含一个Form首部行和To首部行,也许包含一个Subject首部行和其他可选首部行。这些首部是报文的一部分。例如:
然后一个空白行,接下来便是以ASCII码格式表示的报文体。
· · MIME是多媒体邮件扩展,在报文首部用额外的行声明MIME内容类型。如:
· · 邮件访问协议:
· · SMTP:传送到接收方的邮件服务器所使用的协议。
· · 邮件访问协议:有POP、IMAP、HTTP。是从服务器访问邮件所用的协议。
· · · POP3:第三版的邮局协议(Post Office Protocol—Version 3)首先用户身份确认 (代理<–>服务器) 然后下载。
· · · IMAP:Internet邮件访问协议(Internet Mail Access Protocol),比POP有更多特性 (更复杂),并在服务器上处理存储的报文
· · · HTTP:Hotmail , Yahoo! Mail等
,更加方便。
· · 协议的选择可以看下图:
· · · POP3:
· · · 分为三个阶段:特许、事物处理以及更新,且属于无状态协议。
· · · · 第一阶段:用户代理发送用户名和口令以鉴别用户。有两个主要命令:user< user name >和pass < password >。
· · · · 第二阶段:用户代理取回报文;同时可以对报文做删除标记、取消删除标记以及获取邮件的统计信息,发出这些命令。服务器对命令的回答有两种:+OK,指示前面的命令是正常的,-ERR,指示前面的命令出现了差错。
· · · · 第三阶段:它在客户发出quit命令之后,结束该POP3会话;同时该邮件服务器删除那些被标记为删除的报文。
list: 报文号列表
retr: 根据报文号检索报文
dele: 删除
quit: 结束对话,该邮件服务器删除那些被标记为删除的报文。
· · · IMAP
· · · IMAP服务器把每个报文与一个文件夹联系起来;当报文第一次到达服务器时,它与收件人的INBOX文件夹相关联。收件人便可以把邮件转移到新的、用户创建的文件夹,阅读邮件、删除邮件。
· · · IMAP协议为用户提供了创建文件夹以及将邮件从一个文件夹移到另一个文件夹的命令,还提供了在远程文件夹中查询邮件的命令,按指定去查询匹配的邮件,还维护了IMAP会话的用户状态信息。
· · · IMAP协议允许用户代理获取报文组件的命令。
· DNS:因特网的目录服务
· 一台主机的地址为IP地址,但是IP地址不容易被记忆,所以有了主机名,一个字符串,DNS便可以完成主机名和IP地址的转换。
· · DNS提供的服务:
· · DNS(Domain Name System)域名系统,是一个分层的DNS服务器实现的分布式数据库,是一个使主机能够查询分布式数据库的应用层协议。
· · DNS是一种应用层协议,使用客户-服务器模式运行在通信的端系统之间;在通信的端系统之间通过下面的端到端运输协议来传送DNS报文。
· · DNS服务器通常是运行BIND软件的UNIX机器,DNS协议运行在UDP之上,使用53号端口。
· · 主机别名:一个复杂主机名的主机可以拥有多个别名,复杂主机名被称为规范主机名,应用程序可以调用DNS来获得主机别名对应的规范主机名以及主机的IP地址。
· · 邮件服务器别名:电子邮件应用程序可以调用DNS,对提供的邮件服务器别名进行解析,已获得该主机的规范主机名以及IP地址。MX记录允许一个公司的邮件服务器和Web服务器使用相同(别名化的)的主机名。
· · 负载分配:DNS用于在冗余的服务器之间进行负载分配。一个访问次数多的站点被冗余分分布在多台服务器上,所以一个对应的规范主机名有多个IP地址。当一个客户端对该主机名发送一个DNS请求时,该服务器用IP地址的整个集合进行响应,并在每个回答中循环这些地址次序。
· · DNS工作原理:
· · DNS是在因特网上实现分布式数据库
· · · 分布式、层次数据库:
· · · 三类DNS服务器:根DNS服务器、顶级域(TLD、Top-Level Domain)DSN服务器和权威DNS服务器
· · · · 根DNS服务器:
· · · · 因特网2共有13个根DNS服务器,每个根服务器都是一个冗余服务器的网络。
· · · · 顶级域服务器:
· · · · 这些服务器负责顶级域名如com、org、net、edu和gov,以及所有国家的顶级域名如uk、fr、ca和jp。
· · · · 权威DNS服务器:
· · · · 在因特网上具有公共可访问主机的每个组织结构必须提供公共可访问的DNS记录,这些记录将这些主机的,名字映射为IP地址。一个组织机构的权威DNS服务器用来保存这些记录,或者将这些记录储存在某个服务提供商的一个权威服务器上。
· · · · 本地DNS服务器:
· · · · 每一个ISP都有一个本地DNS服务器(默认名字服务器),当主机与ISP连接时,ISP提供一台主机的IP地址,该主机具有一台或多台其本地DNS服务器的IP地址,通过访问Windows或UNIX的网络状态窗口,能够确定本地DNS服务器的IP地址。
以上几类DNS服务器便是DNS系统中的主要部分,是层次分明的结构体系。
· · · DNS服务器的交互:
· · · 主机cis.poly.edu首先向它的本地DNS服务器dns.ploy.edu发送一个DNS查询报文,该报文含有目的主机的域名(gaia.cs.umass.edu)。本地DNS服务器发送给根DNS服务器,根DNS服务器注意到有edu前缀,然后向本地DNS服务器返回负责edu的TLD服务器的IP地址,然后本地DNS服务器再向这些TLD服务器之一发送查询报文,这些TLD服务器注意到umass.edu前缀,所以向本地DNS服务器返回权威DNS服务器的IP地址,该权威DNS服务器负责目的主机域名和IP地址的联系,最后权威DNS服务器将向本地DNS服务器返回目的主机的IP地址。
· · · 上图的请求主机到根DNS服务器是递归查询,由根服务器最终查询到目的主机IP地址是迭代查询。下图是全部用递归查询:
· · · DNS缓存:
· · · 为了改善延时性能并减少在英特网上到处传输的DNS报文数量,DNS广泛使用了缓存技术。在一个请求链中,如果某个DNS服务器(可以不是目的主机的权威DNS服务器)缓存了目的主机名到其IP地址的映射,那么该DNS服务器将会直接返回此映射。本地DNS服务器也能缓存TLD服务器的IP地址,允许本地DNS绕过查询链中的根DNS服务器。
· · DNS记录和报文:
· · 共同实现DNS分布式数据库的所有DNS服务器储存了资源记录(Resource Record,RR),RR提供了主机名到IP地址的映射。每个DNS回答包含了一条或多条资源记录。
· · · 资源记录(包含四个字段的4元组):
· · · (Name,Value,Type,TTL)
TTL是该记录的生存时间,决定了资源记录应当从缓存中删除的时间,以下例子省略了TLL。Name和Value取决于Type:
Tyep是A,则Name是主机名,Value是主机名对应的IP地址。例如(relat.bae.foo.com, 145.27.93.126, A)。
Tyep是NS,则Name是个域(如foo.com),而Value是个知道如何获得该域中主机IP地址的权威DNS服务器的主机名。例如(foo.com, dns.foo.com, NS)。
Type是CNAME,则Value是别名为Name的主机对应的规范主机名。该记录能向查询的主机提供一个主机名对应的规范主机名,例如(foo.com, relay1.bar.foo.com, CNAME)。
Type是MX,则Value是个别名为Name的邮件服务器的规范主机名。例如(foo.com, mail.bar.foo.com, MX)。MX允许有邮件服务器主机名具有简单的别名。通过使用MX记录可以使邮件服务器和其他服务器具有相同的别名。
· · · 如果一台DNS服务器是用于特定主机名的权威DNS服务器,那么该服务器会包含一条包含该主机名的类型A记录。如果该主机不是其权威DNS服务器,它也能够在缓存中包含一条类型A记录。
· · · 一个DNS服务器也能包含一条类型NS记录,该记录对应于包含主机名的域,还包含一条A记录,该记录提供了NS记录中Value字段中的DNS服务器的IP地址。
· · · DNS报文:
· · · DNS查询和回答报文具有相同的格式:
· · · · 首部区域:
· · · · 前12个字节是首部区域,其中包含了几个字段。
· · · · 标识符字段是一个16bit的数,用于标识该查询,此标识符会被复制到对应查询的回答报文中,以便让客户用它来匹配发送的请求和接收到的回答。
· · · · 标志字段中有许多标志,其中有1bit用来标志此报文是查询报文还是回答报文,0表示查询报文,1表示回答报文。当DNS服务器是所请求名字的权威DNS服务器时,1bit的权威标志位被置于回答报文中。还有希望递归的标志位等等。
· · · · 在该首部中还有4个有关数量的字段,这些字段指出了在首部后的4类数据区域出现的数量。
· · · · 问题区域:
· · · · 包含了名字字段:指出正在被查询的主机名字;类型字段:指出有关该名字的正在被查询的问题类型(就是资源记录类型A, MX等等)。
· · · · 回答区域:来自DNS服务器的回答中,包含了对起初请求的名字的资源记录。在回答区域可以包含多条RR,因此一个主机名能够有多个IP地址(这里就像冗余的Web服务器)。
· · · · 权威服务器:包含了其他权威服务器的记录。
· · · · 附加区域:包含了其它有用的信息。
· · · 向DNS数据库中插入数据:
· · · 当一台服务器需要加入DNS体系时,并允许别人访问自己的服务器站点时,需要向注册登记机构注册域名,向该机构提供此服务器的基本和辅助权威DNS服务器的名字和IP地址。
· · · 该机构对这两个权威DNS服务器的每一个,都建立类型NS和类型A的记录。并确保在这两个权威DNS服务器中存在Web服务器的类型A资源记录或用于邮件服务器的类型MX资源记录。
· P2P应用:
· 使用P2P体系结构,可以对总是打开的基础设施服务器有最小的依赖。任何端系统可以直接通信,每次的IP地址可能发生变化。应用于文件分发、流媒体、VoIP等。
· · P2P文件分发:
· · 在客户端—服务器文件分发中,如果客户端数量过大,而服务器需要向每个客户端发送该文件的副本,导致客户端消耗了大量的服务器带宽。而在P2P文件分发中,每个对等方能够重新分发它所有的该文件的任何部分,从而在分发过程中协助到服务器。
· · · P2P体系结构的扩展性:
· · · 分发时间:所有对等方得到该文件的副本所需要的时间。
· · · 通过计算可以比较出两种模式的文件分发时间:
· · · BitTorrent:
· · · BitTorrent是一种用于文件分发的流行P2P协议。参与一个特定文件分发的所有对等方的集合被称为一个洪流,在一个洪流中的对等方彼此下载等长度的文件块,一个典型的文件块是256KB,当一个对等方首次加入洪流时,它没有块,随着时间的推移,它会积累越来越多的块,当获取整个文件时,它可以选择离开,也可以选择留下为其它对等方上载块。所有的对等方可以在任何时候仅具有块的子集就离开洪流,并能在以后重新加入洪流中。
· · · 每个洪流都由一个基础设施节点,称为追踪器。当一个对等方加入某洪流时,她向追踪器注册自己,并周期性地通知追踪器它任在该洪流中。追踪器通过这种方式,追踪正在参与洪流汇总的对等方。
· · · 当一个对等方A加入洪流时,追踪器随机的从对等方集合中选出一个子集,并将这些对等方的IP地址发送给A,A收到这张子集列表之后,可以选择与该列表上的所有对等方创建并行的TCP连接,(我们称建立连接的对等方为邻近对等方),随着时间的流逝,A的邻近对等方可能会减少或增多。
· · · 在一定时间内,A周期性地询问每个邻近对等方它们所具有的块列表,经查询后,A可以将它当前没有的块发出请求(TCP)。
· · · 可能有多个邻近对等方具有A所未有的块,在决定请求的过程中,A使用了稀缺优先的技术,在它的邻近对等方中决定最稀缺的块(也就是那些在它的邻居中副本数量最少的块),并请求那些最稀缺的块,这样的请求可以快速地使最稀缺的块与其它块均衡。
· · · 还有种情况是,A可能会向多个邻居发送块,它需要优先决定向谁发送。BitTorrent使用了一种对换算法。A根据当前能够以最高速率向它提供数据的邻居给出优先权。
· · 分布式散列表:
· · 在P2P系统中,每个对等方将保持(键,值)对仅占总体的一个小子集。允许任何对等方用一个特别的键来查询该分布式数据库。分布式数据库将定位拥有该相应的(键,值)对的对等方,然后向查询的对等方返回该(键,值)对。任何对等方也将允许在数据库中插入新键-值对,这样的一种分布式数据库被称为分布式散列表(Distributed Hash Table,DHT)。
· · 环形DHT: 在DHT中,为每一个对等方分配一个标识符,将这些对等方组织为一个环,在环中,每个对等方仅与它的直接后继和直接前任联系。在设计DHT中,可以为对等方添加多个捷径,使得每个对等方不仅联系它的直接后继和直接前任,而且在联系分布在环上的数量相对少的捷径对等方。
· · 对等方扰动: 在P2P系统中,对等方可以直接到来和离去(不需要提前告知)。每个对等方都保留了第一个后继和第二个后继,当一个对等方的第一个后继离开后,它开始联系它的第二个后继,然后代替第一个后继,并将新的第一个后继的直接后继作为它的第二个后继。当一个对等方要加入时,它首先向它唯一知道的对等方发送报文,请求它的后继和前任,得知后继和前任后,通过环结构将它与前任与后继联系起来。
· 套接字编程
· 开发者创建一个网络程序时,主要任务就是编写客户程序和服务器程序的代码,而客户程序与服务器程序是通过套接字读出和写入数据进行通信的。
· 网络应用程序分为两类:一类实现在协议标准中定义的操作,这类程序由可以由不同的程序员单独开发。第二类时专用的网络应用程序,这种情况下,由客户和服务器程序应用的应用层协议没有公开发布在RFC中。
· · TCP套接字编程:
· · · 大致流程:
· · · 服务器首先运行,等待连接建立:服务器进程必须先处于运行状态;创建欢迎socket,并和本地端口捆绑,在欢迎socket上阻塞式等待接收用户的连接。
· · · 客户端主动和服务器建立连接,客户套接字需要与服务器的欢迎套接字进行三次握手。
· · · 创建客户端本地套接字(隐式捆绑到本地port),指定服务器进程的IP地址和端口号,与服务器进程连接。
· · · 当与客户端连接请求到来时,服务器接受来自用户端的请求,解除阻塞式等待,返回一个
新的socket(与欢迎socket不一样),与客户端通信。
· · · 允许服务器与多个客户端通信,使用源IP和源端口来区分不同的客户端。当连接API调用有效时,客户端与服务器建立了TCP连接。
· · · TCP在客户端和服务器进程之间提供了可靠的、字节流(管道)服务。
· · · 流程图:
· · · 代码实现:
· · · · 数据结构sockaddr_in
//IP地址和port捆绑关系的数据结构(标识进程的端节点)
struct sockaddr_in {
short sin_family; //AF_INET
u_short sin_port; // port
struct in_addr sin_addr ;
// IP address, unsigned long
char sin_zero[8]; // align
};
· · · · 数据结构hostent
struct hostent
{
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length; /*地址长度*/
char **h_addr_list;
#define h_addr h_addr_list[0];
}
· · · · 客户端程序(client.c)
void main(int argc, char *argv[])
{
struct sockaddr_in sad; /* structure to hold an IP address of server */
int clientSocket; /* socket descriptor */
struct hostent *ptrh; /* pointer to a host table entry */
char Sentence[128];
char modifiedSentence[128];
host = argv[1]; port = atoi(argv[2]);
clientSocket = socket(PF_INET,SOCK_STREAM,0);
memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
sad.sin_family = AF_INET; /* set family to Internet */
sad.sin_port = htons((u_short)port);
ptrh = gethostbyname(host);
/* Convert host name to IP address */
memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
//将IP地址拷贝到sad.sin_addr
connect(clientSocket, (struct sockaddr *)&sad, sizeof(sad));
服务器程序(server.c)
void main(int argc, char *argv[])
{
struct sockaddr_in sad; /* structure to hold an IP address of server*/
struct sockaddr_in cad; /*client */
int welcomeSocket, connectionSocket; /* socket descriptor */
struct hostent *ptrh; /* pointer to a host table entry */
char clientSentence[128];
char capitalizedSentence[128];
port = atoi(argv[1]);
welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
sad.sin_family = AF_INET; /* set family to Internet */
sad.sin_addr.s_addr = INADDR_ANY; /* set the local IP address */
sad.sin_port = htons((u_short)port);/* set the port number */
bind(welcomeSocket, (struct sockaddr *)&sad, sizeof(sad));
listen(welcomeSocket, 10)
while(1) {
connectionSocket=accept(welcomeSocket, (struct sockaddr *)&cad, &alen);
n=read(connectionSocket, clientSentence, sizeof(clientSentence));
/* capitalize Sentence and store the result in capitalizedSentence*/ n=write(connectionSocket, capitalizedSentence, strlen(capitalizedSentence)+1);
close(connectionSocket); //关闭这个连接进程的socket,继续等待下一个socket。
}
}
· · UDP套接字编程:
· · 在客户端和服务器之间没有连接,没有握手。发送端在每一个报文中明确地指定目标的IP地址和端口号。 服务器必须从收到的分组中提取出发送端的IP地址和端口号。
UDP: 传送的数据可能乱序,也可能丢失。
客户端代码(client.c)
/* client.c */
void main(int argc, char *argv[])
{
struct sockaddr_in sad; /* structure to hold an IP address */
int clientSocket; /* socket descriptor */
struct hostent *ptrh; /* pointer to a host table entry */
char Sentence[128];
char modifiedSentence[128];
host = argv[1]; port = atoi(argv[2]);
clientSocket = socket(PF_INET, SOCK_DGRAM, 0); //这里创建客户端socket,但是没有连接到服务器。
/* determine the server's address */
memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
sad.sin_family = AF_INET; /* set family to Internet */
sad.sin_port = htons((u_short)port);
ptrh = gethostbyname(host);
/* Convert host name to IP address */
memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
服务器程序(server.c):
void main(int argc, char *argv[])
{
struct sockaddr_in sad; /* structure to hold an IP address */
struct sockaddr_in cad;
int serverSocket; /* socket descriptor */
struct hostent *ptrh; /* pointer to a host table entry */
char clientSentence[128];
char capitalizedSentence[128];
port = atoi(argv[1]);
serverSocket = socket(PF_INET, SOCK_DGRAM, 0);
memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
sad.sin_family = AF_INET; /* set family to Internet */
sad.sin_addr.s_addr = INADDR_ANY; /* set the local IP address */
sad.sin_port = htons((u_short)port);/* set the port number */
bind(serverSocket, (struct sockaddr *)&sad, sizeof(sad));
while(1) {
n=recvfrom(serverSocket, clientSentence, sizeof(clientSentence), 0
(struct sockaddr *) &cad, &addr_len );
/* capitalize Sentence and store the result in capitalizedSentence*/
n=sendto(serverSocket , capitalizedSentence, strlen(capitalizedSentence)+1,
(struct sockaddr *) &cad, &addr_len);
}
}
以上代码实现的是从客户端发送一串字符串,然后由服务器改为大写之后返回给客户端。