应用层协议原理
- 客户-服务器体系结构:
特点:客户之间不能直接通信;服务器具有周知的,固定的地址,该地址称为IP地址。
配备大量主机的数据中心常被用于创建强大的虚拟服务器; - P2P体系结构:
特点:对位于数据中心的专用服务器有最小(或者没有)依赖
P2P最引人入胜的特征之一是它具自扩展性:尽管每个对等方都由于请求文件产生工作负荷,但是每个对等方通过向其他对等方发送文件也为系统增加服务能力。 - 进程通信:
套接字是同一台主机内应用层与运输层之间的接口,也被称为应用程序和网络之间的应用程序编程接口(API)。 - 进程寻址:
在因特网中,主机由其IP地址标识,而目的主机中到底是哪个应用程序?它由端口号表示。 - 可供应用程序使用的运输服务:
- 可靠数据传输:
应用程序的一端发送的数据正确,完全地交付给该应用程序的另一端,如果一个协议提供了这样的确保数据交付服务,我们就认为提供了可靠数据传输服务。 - 吞吐量
- 定时
- 安全性
- 可靠数据传输:
- 因特网提供的运输服务:
- TCP服务:
TCP服务模型包括面向连接服务和可靠数据传输服务。除此之外,TCP还提供拥塞控制机制。
SSL:安全套接字层 - UDP服务:
UDP是一种不提供不必要服务轻量级运输协议。
- TCP服务:
Web和HTTP
Web的应用层协议是HTTP(超文本传输协议)协议,它是Web的核心。
HTTP使用TCP作为它的支撑运输协议
HTTP是一个无状态协议。
HTTP在默认情况下使用持续连接。
1.HTTP报文格式
-
HTTP请求报文:
GET /somedir/page.html HTTP/1.1 Host:www.someschool.edu Connection:close Uset-agent:Mozilla/5.0 Accept-language:fr
HTTP请求报文的第一行被称作请求行,其后继的行叫做首部行。
请求行有三个字段:方法字段,URL字段和HTTP版本字段。
在方法字段中是,可以包括GET,POST,HEAD,PUT和DELETE,绝大部分的HTTP请求报文都使用GET方法。
URL字段中包含了请求对象的标识。
版本字段是自解释的。
首部行Host:www.someschool.edu指明了对象所在的主机。
通过包含Connection:close首部行,告诉服务器不必要使用持续链接,在发送完被请求的对象之后就关闭连接。
User-agent:向服务器指明用户代理,即浏览器类型,以便于服务器发送对象的不同版本(如果有的话)。
Accept-language:告诉浏览器用户想得到的对象的语法版本(如果有的话)。
-
其中,使用POST方法的时候才使用实体体,例如,用户向搜索引擎搜索关键词时,实体体中就是用户在表单字段输入的值。
用表单生成的请求报文不是必须使用POST方法!,例如www.somesite.com/animalsearch?monkes&bananas
这时用户输入的内容就是moknkey和banana。 -
HEAD方法类似与GET方法,但是服务器不返回请求对象,应用程序开发者通常使用HEAD方法进行调试跟踪。
-
PUT方法通常与web发行工具联合使用,它允许用户上传对象到指定的Web服务器上的指定路径(目录)。
-
PUT也常被那些需要向Web服务器上传对象的一个用程序使用。
-
DELETE方法允许用户或者应用程序伤处Web服务器上的对象。
-
HTTP响应报文
HTTP/1.1 OK Connection:close Date:Tue,18 Aug 2015 15:11:33 GMT Sever:Apache/2.2.3 (CentOS) Last-Modified:Tue,18 Aug 2015 15:11:03 GTM Content-Length:6821 Contect-Type:text/html (data data data data ... )
我们来看看这个响应报文:它有三个部分:状态行,首部行和实体体,这是上面那个请求报文的响应报文。
我们来看看首部行:- Connection close:服务器用这个首部行告诉客户:发送完报文后,我将关闭TCP连接
- Dtae:指示服务器产生并且发送该报文的日期和时间
- Sercer:服务器的版本,这里指示该服务器时Apache Web服务器
- Last-Modified:所请求的对象创建或者最后修改的时间
- Content-Length:指示了被发送对象中的字节数
- Content-Type:指示了实体体中的对象是什么类型,对象类型应该正式地由该首部行指示,而不是根据文件扩展名来展示
- 响应报文格式:
2.cookie:
cookie技术含有四个组件:
- 在HTTP响应报文中的一个cookie首部行
- 在HTTP请求报文中的一个cookie首部行
- 在用户端系统中有一个cookie文件,并且由用户浏览器管理
- 位于Web站点的一个后端数据库
3.Web缓存:
Web缓存器也叫做代理服务器。简单来说,就是在客户端与服务器之间,安装一个Web缓存器,该缓存器靠近客户端,当客户访问一个Web页面时,HTTP请求报文被Web缓存服务器接收,如果该Web缓存服务器上有客户请求的对象,则直接返回给客户,如果没有的话,则由该Web缓存服务器向Web服务器发送HTTP请求,Web服务器返回的对象由该Web缓存服务器接受并保存,然后返回给客户,这样,当第二次访问或者被配置到该Web缓存服务器的客户访问该站点的时候,Web缓存服务器就能快速做出回应。
Web缓存服务器的优势:
- 大大减少客户请求响应的时间。
- 大大减少一个机构的介入链路到互联网的通信量。
4.条件GET方法:
回想我们上面讲过的Web缓存,你有没有发现一个问题?就是如果一个Web页面被Web缓存器保存了,如果说,Web服务器后来更新了该页面,那么不是会出现问题吗?
解决这个问题的方法就是条件GET方法:
当用户请求某个页面的时候(正好该Web缓存服务器上有缓存),那么该Web缓存服务器就向Web服务器发送一个条件GET报文:
GET /fruit/kiwi.gif HTTP/1.1
Host:www.exotiquecuisine.com
If-modified-since:Wed,9 Sep 2015 09:23:24
这里需要注意:这里的If-Modified_since首部行的值,就是该Web缓存服务器中,上一次接收到该对象的Last-Modified时间,也就是说,该Web缓存器告诉Web服务器:如果这个时间之后你们改变了对象,那么你就把新的给我发过来。
如果该对象没有被改变,则Web服务器发送响应报文:
HTTP/1l1 304 Not Modified
Date:Sat,10 Oct 2015 15:39:29
Server:Apache/1.3.0(Unix)
(empty extity body)
注意该响应报文中并没有包含对象,如果说,Web服务器上没有更新该对象的话,那么此报文中包含对象只会浪费带宽。
英特网中的电子邮件
邮箱系统的组成部分:用户代理,邮件服务器,简单邮件传输协议(STMP),信箱
- STMP与HTTP的对比:
- HTTP是一个“拉协议”,而STMP是一个“推协议”
- STMP要求每个报文使用7字节ASCII码形式,而HTTP数据不受这个限制
- 邮件访问协议:
用户之间发送邮件的时候,邮件被保存在了我的邮箱代理中了,但是我怎么查看邮件?STMP是一个推协议,我不能拉回来呀,所以就出现了邮件访问协议,目前流行的邮件访问协议有:第三版的邮局协议(POP3),因特网邮件访问协议(IMAP)以及HTTP。
DNS(域名系统):英特网的目录服务
因特网上的主机像人一样,我们也希望标识,主机可以使用主机名和IP地址来标识,但是我们更倾向于记住它的主机名而不是IP地址,所以,需要在主机名和IP地址之间进行转化,DNS就承担了这项任务。
DNS是:①一个有分层的DNS服务器实现的分布式数据库,②一个使得主机能够查询分布式数据库的应用层协议。
DNS协议运行在UDP之上,使用53号端口。
除了进行主机名到IP地址的转换之外,DNS还提供了一些重要的任务:
- 主机别名
- 邮件服务器别名
- 负载分配
DNS工作机理概述:
- DNS一种简单的设计是在英特网上只用一个DNS服务器,该服务器包含所有的映射。
但是这种设计肯定存在很多问题:- 单点故障:如果说这个服务器发生了故障,整个因特网将瘫痪!
- 通信容量:这个服务器要处理来自因特网上所有的DNS查询。
- 远距离的集中式数据库:有时候真的可能要跨越半个地球!这中间可能有低俗的拥塞链路,那将会特别慢!
- 维护:如果说出现了一个新的主机,他就要维护。
那么解决方法有哪些?我们来看看:
- 分布式,层次数据库:
其中包括:根DNS服务器,顶级域(DNS)服务器,权威DNS服务器,还包括本地DNS服务器,但是要注意本地DNS服务器不属于该服务器的层次结构!
在实践中,通常从请求主机到本地DNS服务器的查询是递归查询,其他的查询都是迭代查询。 - DNS缓存
因为有缓存机制的存在,除了少数DNS查询以外,跟服务器都被绕过了。
P2P文件分发
我们之前讲述的客户-服务器的体系结构,总是要求服务器是打开的,使用P2P体系结构,能够对总是打开的基础设置服务器有最小的(甚至没有)依赖。
对等方不仅是比特的消费者,还是它们的重新分发者。
视频流和文件分发网
HTTP
经HTTP的动态适应性流(Dynamic Adaptive Streaming over HTTP)(DASH)
- 内容分发网(CDN)
专用CND和第三方CND
套接字编程
-
UDP套接字编程:
UDPClient.py:from socket import * serverName = 'hostname' serverPort = 12000 clientSocket = socket(AF_INET,SOCK_DGRAM) message = raw_input('Input lowercase sentencte:') clientSocket.sendto(message.encode(),(serverName,serverPort)) modifiedMessage,serverAddress = clientSocket.recvfrom(2048) print(modifiedMessage.decode()) clientSocket.close()
UDPServer.py:
from socket import * serverPort = 12000 serverSocket = socket(AF_INET,SOCK_DGRAM) serverSocket.bind('',serverPort) print("The server is ready to receive") while True:message,clientAddress = serverSocket.recvfrom(2048)modifiedMessage = message.decode().upper()serverSocket.sendto(modifiedMessage.encode(),clientAddress)
-
TCP套接字编程:
TCPClient.py:from socket import * serverName = 'servername' serverPort = 12000 clientSocket = socket(AF_INET,SOCK_STREAM) clientSocket.connect((serverName,serverPort)) sentence = raw_input('Input lowercase sentence') clientSocket.send(sentence.encode()) modifiedSentence = clientSocket.recv(1024) print('From Server: ',modifiedSentence.decode()) clientSocket.close()
TCPServer.py:
from socket import * serverPort = 12000 serverSocket = socket(AF_INET,SOCK_STREAM) serverSocket.bind(('',serverPort)) serverSocket.listen(1) print('The Server is ready to receive') while True:connectionSocket,addr = serverSocket.accept()sentence = connectionSocket.recv(1024).decode()capitalizedSentence = sentence.upper()connectionSocket.send(capitalizedSentence.encode())connectionSocket.close()