【事先声明】
这是对于中科大的计算机网络的网课 的学习笔记,感谢郑烇老师 的无偿分享
书籍是《计算机网络(自顶向下方法 第6版)》
需要的可以私信我,无偿分享,课程简介下也有
课程连接
目录
- 应用层网络应用的原理
-
- 应用架构
- 进程间通信
-
- 分布式进程通信要解决的问题
- 解决
-
- 对进程进行编址
- 传输层提供服务-应用层需要提供的信息
-
- socket(套接字)
- [TCP socket](#TCP socket)
- [UDP socket](#UDP socket)
- 对比
- 基于应用层定义的协议
- Web与HTTP
- FTP:文件传输协议
- DNS
- P2P应用
- CDN
- Socket编程
- 总结
应用层网络应用的原理
应用架构
客户端-服务端模式(C/S)
服务端必须要比客户端先运行
- 服务端一直运行
- 有固定的IP和已经约定好了的端口
- 可扩展型差,可以通过增加服务器的数量来增强对于客服端的服务,但是网络质量难以提升
客户端
- 主动与服务端通信,请求资源
- 可以是动态的IP地址
- 不直接与其它客户端通信,一切都由服务端来处理
对等模式(P2P)
对于C/S的中心模式,P2P去中心化,每个节点即可以请求别的节点的数据资源,也可以响应别的节点的数据与资源(为其它节点提供服务)
缺点是不好管理,资源也没办法集中。
混合体
对于前面两种模式的中和
有一台中心服务器(简单模型),然后有很多用户,用户有一定规模。
每当用户上线时,就会向服务器报告,自己拥有的资源目录。服务器就可以知道自己的用户所有用的资源数量以及目录。
当一个用户想要下载一个资源时,会向服务器请求这个资源,然后服务器就可以在已经上线的用户资源目录表中进行查找,可以差找到多个用于拥有这个资源,就会发送命令,让这个几个拥有资源的用户向那个请求资源的用户IP发送自己拥有的资源。然后服务请对于资源的发送进行管理,保证数据的有序与完整性。
这样就相当于多台服务器在向一个用户发送资源,一台服务器发送一部分资源,然后中心服务器组织管理后,就可以变成一个完整的资源。这样肯定比一台服务器发送资源速度更快,还可以多次进行校验,确保数据的完整性。
当用户越多,拥有的资源就越多,中心服务器可以管理的资源就越多 ,用户下载资源的速度就更快,就会吸引更多的用户进来。
P2P的方式发送资源,C/S的模式管理资源
进程间通信
应用层的协议要在传输层可以确保进程与进程间的通信(不同机器)的基础上,才能进行操作。
- 客户端进程:发起通信的进程
- 服务端进程:等待连接的进行(被动响应客户端的进程)
P2P架构中,也是有客户端进程与服务端进程的区分
分布式进程通信要解决的问题
进程标示与寻址问题
一个客户端进程发送请求,得让服务端进程知道 请求这个数据的客户端进程 的唯一标志,并且可以根据这个唯一标志进行寻址,不然数据都不知道发给谁。
传输层是如何为应用层提供服务
应用层通过调用层间的SAP,通过使用指定的API来获得网络通信的服务。
如何使用传输层的服务进行应用进程之间的报文交换,实现应用的服务
定义应用层之间的协议,报文格式,指定动作,时序...
通过OS提供的系统API,以及下层提供的通信服务API,来实现这些配置
解决
对进程进行编址
进程为了接收与发送报文,必须要有一个标识。
- 主机地址:唯一的32位IP地址
- 采用的传输层的协议:TCP/UDP
- 端口号:协议上的port
一个进程可以用这三个唯一标识
本质上,一对主机进程之间的通信可以由两个端节点构成:IP+协议port

传输层提供服务-应用层需要提供的信息
层间接口需要获得的信息
- 要传输的报文:SDU(要发送的数据)
- 自己进程的标示:IP地址+传输层协议+端口号
- 对方进程的标示:对方的IP地址+传输层协议+端口号
总结一下:传输层提供服务需要从应用层获得的信息有:要发送的数据,谁发的,发给谁的
传输层会根据这些进行进行封装成本层协议的报文段。

如果每次都传输一个这样完整的数据,会很麻烦。
在要时序一段时间都会发送一定数据的情况下,想办法省去前面的数据,只发送SDU。
socket(套接字)
可以利用API,表示通信的双方或者单方,就像利用OS提供的API打开文件一样,打开一次就够了,不用每次使用都fopen一下。
TCP socket
- TCP服务,两个进程会持续一段时间进行通信发送数据,通信关系比较稳定
- 可以用一个类型的变量表示两个应用实体,本地表示(向对方进行发送数据,可以抽象成对这个变量/标示进行操作)
- 这样可以减少穿过层间的信息量
- TCP socket:源IP,源端口,目标IP,目标端口。有这些组成的本地标示,类似于fopen返回的文件描述符。

TCP socket表示的是一个会话关系,两台主机之间的会话关系。
UDP socket
UDP服务:两个进程之间通信之前不用建立连接。
- 每个报文都是独立传输的
- 前后两个报文可能是传输给不同的分布式进程
所以,只是用一个本地的变量/标示 代表本应用(源进程)的源IP与源端口,因为UDP的目标分布时进程是不确定的。
UDP socket:源IP、源端口
不过传输时,必须 要知道目标IP与目标端口,虽然UDP socket并不维护目标IP与目标端口,但是应用层必须需要将目标IP与目标端口发给传输送层。

对比
与TCP socket相比,UDP套接字建立好后,需要发送SDU与目标IP、目标端口。
而TCP套接字建立好后,只需要发送SDU即可,因为TCP是建立好两个进程之间的连接的。

进程可以通过socket这个门户,基于传输层提供的基础服务上,实现报文交换

基于应用层定义的协议
- 交换报文的类型:进程之间请求和应答的报文
- 报文的语法:报文中各个字段及其描述
- 字段的语义:字段取值的含义
- 进程发送报文的时间以及响应报文该做的动作
传输层提供服务

为什么要存在UDP?
对于实时性要求高 ,对可靠性要求不高的应用需要这样的服务。
UDP存在的必要性
- 可以利用端口号区分不同的进程,IP只能保证主机到主机之间的通信
- 无需建立连接,省去了建立通信所耗费的时间
- 不做可靠性的任务,适合对实时性要求高,对可靠性要求不高的任务
- 不会进行拥塞控制与流量控制,可以保证数据按照设定的速度发送
安全性SSL
TCP与UDP都不提供加密服务,对于数据都是明文传输的,如果对数据进行抓包甚至可以获得密码等关键信息。
不过可以在应用层中使用SSL,进行数据加密,然后由传输层协议将加密后的数据传输到指定进程,这样可以保证安全性。

传输层提供服务的衡量

常见应用层应用对于传输层服务的要求

Web与HTTP

网页中的图片之类的对象,并不一定是对象本身,而是对象的URL链接。
任何一个对象都可以被一个URL唯一表示。
URL格式

通过这个URL,可以访问互联网中的任何一个对象。
HTTP协议
超文本传输协议,Web的应用层协议
C/S模式
在客户端雨服务端建立TCP的连接后,客户端向服务端发送HTTP的请求,服务端将客户端请求的对象封装成HTTP的报文,然后发送回客户端。

HTTP协议工作
- 客户端发起一个与服务端的TCP连接,设置好一个端口号为80的TCP套接字
- 服务端接受客户端的TCP连接
- 在客户端(HTTP客户端)与Web(HTTP服务端)交换HTTP报文(两个进程在以应用层的HTTP协议交换数据)
- TCP连接关闭

然后客户端获得服务端发送的HTTP报文,如果其中由URL,客户端就会根据URL中的主机、端口号,再次发送HTTP报文,去获得指定服务端中的对应的资源,因为资源可能存放在别的服务器中。
HTTP是无状态的:服务器不需要维护关于客户的任何状态,HTTP协议并不记录关于客户端请求的各种数据,只要请求,就按照请求响应即可。
优点是非常简单,响应速度非常快,可以支持更多的客户端请求。

HTTP连接
非持久HTTP连接
TCP连接建立后,客户端发送一次HTTP请求后,服务端根据请求发送HTTP回应,然后TCP就断掉连接,这种只能进行一次HTTP报文交换。
执行步骤
- 客户端从port:80向服务端的IP发送一个TCP连接,在协议栈的提供的网络基础下,客户端与服务端都会建立一个与之对应的TCP socket(套接字),对套接字操作就是对同层次的实体进行操作。
- 客户端对套接字发送一个HTTP请求报文,这个请求报文中,包含着请求的对象在服务端中的地址。
- 服务端经过套接字可以拿到HTTP请求报文,然后从报文中可以得到请求的对象在服务器的ROM中的地址,然后进行检索,拿到请求的对象,然后再HTTP响应报文中封装对象,再对套接字进行操作,给客户端发送响应报文。
- 服务端会通知客户端断开TCP连接,TCP在确定客户端已经收到HTTP响应报文后才会断开与服务端的连接。
- 客户端对HTTP报文进行解封装,提取出HTML文件,然后检查HTML文件,可以得到若干个URL,然后再去将URL封装成HTTP请求报文,不断执行步骤一,不断建立TCP连接,发送HTTP请求,获得HTTP响应,断开TCP连接...直到所有的URL都被加载到客户端中。
TCP建立连接->发送HTTP请求->获得HTTP请求->断开TCP连接
该TCP连接只能传输一个请求报文和一个响应报文,即这种一次非持久性连接只能实现传输一个对象。
如果客户端请求的是一个Web网页,网页中包含着一个HTML文件与10个图片资源的URL,则这种非持久性连接,需要进行11次,才能在客户端的网站上展示一个完整的网页。
不过,这里并没有说请求10个URL的HTTP报文时,是串行的还是并行的。
现代浏览器可以设置并行HTTP请求数,当设置为1时,就可以保证是串行请求,默认情况下,浏览请通同时进行5-10个HTTP请求是没问题的,并行请求比较快。
RTT(Round-Trip Time)
定义:一个短分组 从客户端到服务端,再从服务端返回客户端,这一去一回所花费的时间。
对于非持久性连接的时间计算
- 客户端发送TCP报文段请求建立连接,服务端发送一个TCP报文段 确认连接--一个RTT
- 客户端发送一个HTTP请求报文,服务端发送一个HTTP响应报文 --一个RTT
- 服务端在TCP连接上发送文件所花费的传输时间
总的时间:2个RTT+一个文件传输时间

持久性HTTP连接
如果使用非持久性连接,则传输n个对象则需要2n*RTT
的时间,如果是n个用户,请求n个对象,则需要耗费2n^2*RTT
的时间与空间资源,因为想要进行TCP连接,则需要服务请为其开辟一定的空间作为缓存,这个空间资源的消耗是巨大的。
如果是对于一个用户请求n个对象,则可以不关闭TCP连接,一直保持连接,直到请求结束后或者超过一定的时间间隔没有请求,才断开TCP连接。这样对于时间的花费只有(n+1)*RTT
。对于空间资源的消耗,可以一直使用之前开辟的那块缓存空间。学习过OS的人都知道,向系统申请空间资源也是需要花费一定的时间的,如果是频繁的向系统申请资源,会严重拖慢系统的运行速度,这样才会出现内存池的设计(提前申请出一定空间资源,需要的时候直接使用,避免时间开销)。

对比

HTTP报文格式
HTTP报文只有请求报文和响应报文两种格式
不同版本的HTTP协议,有不同的命令

请求报文

- 请求行:命令 请求对象 HTTP协议的版本
- Host:指明对象所在的主机
- User-agent:用户代理,向服务器发送请求的浏览器的类型
- Connection:连接方式,默认是持久性连接,close后,变成了非持久性连接,传输一个对象后就断掉TCP连接
- Accept-language:网页的语言,如果服务端有,就发送对应的版本,如果没有就发送默认的语言版本
HEAD命令,向服务器请求HTML的头部,对象不返回,一般用于调试跟踪,爬虫似乎也这样用。
如果请求命令是POST,则首部行后面还会加一个实体体,表示要向服务器提交的对象
PUT与DELETE命令,通常是网络管理员使用的
如果是搜索内容,那么实体主体中就是输入的要搜索的内容

向服务器提交内容
POST
向服务器提交表单,表单的内容就会在实体主体中。
GET
在请求行,URL后面,以参数的形式进行提交
响应报文

状态行
- 协议版本
- 状态码 状态码对应的短语(给人看的)

连接方式
- 默认是持久性连接
- close表示是非持久性连接
Date
服务器产生并响应发送该报文的时间
Server
服务器的类型是一台 Apache Web 服务器
Last-Modified
对象创建或最后的修改时间
对于即可能存在本地客户,也可能存在网络服务器缓存中的对象非常重要(跟数据一致性有关)
Content-length
被发送对象中的字节数
Content-type
被发送对象的类型
通用响应报文格式

cookie
HTTP协议是无状态的
cookie技术可以让站点去记录或跟踪用户,记录用户之前访问网站的信息。
cookie技术组件
- HTTP响应报文中设置一个cookie首部行
- HTTP请求报文中设置一个cookie首部行
- 在用户的设备中保留一个cookie文件,存储cookie数据,由浏览器进行管理
- 在服务器的后端数据库中也会保留一份对应的唯一文件
当用户第一次访问某网站时,服务器后台会为其分配创建一个唯一标识码的cookie文件,并放入后台的数据库中。在客户端中,cookie会记录用户的访问行为。让再次访问这个网站时,请求报文中会带上cookie标识码的首部行,服务器提取后,就会去数据库中那大记录用户行为的cookie文件,然后为其提供相应的服务。
Web缓存
相当于是给服务器加了一层Cache,使用了代理服务器,不直接访问原始服务器。
代理服务器可以重定向浏览器的访问IP,将其指向代理服务器,而不是指向原始服务器。
可以减少网络链路中的流量强度,原始服务器的访问量,提高访问速度。
这个一般是针对各个地区设置若干台Web缓冲器,可以直接在高速局域网内访问命中,不用全部接入公用因特网,减少网络的负载。

可以将相当一部分请求,在高速局域网内完成,剩下的未命中的部分再去共用因特网中访问原始服务器。

条件GET(解决数据一致性)
使用Web缓存器,虽然可以解决服务器与链路流量即访问速度的问题,但是这是相当于对原始服务器数据的多次拷贝,当代理服务器中的数据被改动后,原始服务器中的数据是否同样更新。
这就和内存与Cache的问题一样,保证两处的数据一致性。
当用户请求代理服务器得到响应,然后过一段时间,用户再次访问到了代理服务器,代理服务器并不确定这个资源再原始服务器中是否被修改了,会向原始服务器发送一个If_Modified_Since 上次访问的时间
,让原始服务器判断自从上次时间后,资源是否被修改。

- 如果被修改了,原始服务器就会通过HTTP协议重新发送一份这样资源给代理服务器,文件在实体体中
- 如果没有被修改,原始服务器只需要HTTP相应报文中 状态码
304 No-Modified
,没有被修改

这样通过HTTP协议中的条件GET,可以实现数据一致性。
FTP:文件传输协议
与HTTP协议类似,FTP协议也是需要在TCP连接上进行文件传输的。
与HTTP协议不同的是,FTP是需要建立两个并行的TCP连接。
- TCP控制连接:用于口令验证,列表(获取文件目录)...用于两台主机之间传输控制i信息
- TCP数据连接:实际用于传输文件数据
HTTP是无状态的协议,是不需要记录访问信息的,而FTP需要记录,会在整个会话期间保留用户状态,会跟踪记录用户在数据库文件目录中的访问,得与控制连接绑定起来。
FTP过程
- 客户端会在TCP 21号端口与服务端建立一个TCP控制连接,各自产生控制套接字
- 客户端通过该控制连接向服务端发送用户标示与口令,服务端经过数据库检索验证后,允许客户端发送改变远程目录的命令。
- 当FTP服务器收到一个文件传输的命令后(通过控制TCP发送的),就会发起一个到客户端的TCP数据连接。
- 完成一个文件传输后,服务器就会关闭TCP数据连接
在整个会话过程中,TCP控制连接是始终存在的,而TCP数据连接,传输完一个文件后,就会断开连接。每次传输一次文件就会建立一次新的数据连接。

FTP命令
从客户端到服务端的命令,与从服务端到客户端的回答,都是以7比特的ASCII数据,在TCP连接上进行传输。

回答与报文

组成部分
- 用户代理:记录,编辑等操作邮件的软件,比如邮箱
- 邮件服务器:管理着多个用户的邮箱,用户查看邮件时,代理会访问邮件服务器,经过验证后获取邮箱中邮件
- SMTP(简单邮件传输协议):应用层传输协议
当用户A发送邮件给用户B时,A会通过代理去访问自己的邮箱,然后发送邮件,文件数据封装成一个报文,进入外出报文队列中,等待发送到目标的邮件服务器中。当发送到邮件服务器中,然后会进行一个报文队列,等待分发到目标邮箱中。
SMTP
用于从发送方邮件服务器发送报文到接收方邮件服务器中。

这里有一个情况
SMTP并不会使用中间服务器进行传输,而是直接建立源服务器与目标服务器的TCP连接,即使两台服务器很远。

SMTP是一种持续性连接,一个TCP连接可以发送多个报文数据。
与HTTP协议的对比
- HTTP协议与SMTP协议都可以做到持续性TCP连接
- SMTP是发送协议,而HTTP不仅仅可以发送也可以接收协议
- SMTP的每个报文都得是7个比特位的ASCII码格式,而HTTP不受这个限制。
- 对于多个对象数据,HTTP会把每个对象都封装进行多个报文中,多个报文然后发送,而SMTP会把多个对象封装进一个报文中。
SMTP邮件报文格式

邮件访问协议


POP3
极其简单的邮件访问协议
- 特许阶段:用户代理发送用户标示与口令,鉴别用户身份
- 事务处理阶段:代理取回报文,对于报文进行操作,获得邮件统计信息
- 更新阶段:在代理发送断开命令后,根据用户对邮箱的操作,进行更新邮箱。
IMAP
将报文于文件夹管理起来,可以不用讲报文下载到本地,可以远程访问文件夹中的报文信息。
允许用户远程组织报文与文件夹
会记录报文与文件夹的状态,报文ID与目录名之间的映射。
HTTP
基于Web浏览器访问邮箱,变成了C/S模式

DNS
域名解析系统
用于将便于人类记忆的网址解析成IP地址
将人类访问的字符串转换为二进制的网络地址。
DNS解决的问题
1.如何命名设备
- 使用字符串进行替代
- 层次化命名,避免重名,保证唯一标示
2.如何完成名字到IP地址的转换
分布式服务器数据库的访问,避免集中式的访问造成奔溃。
DNS提供的服务
DNS协议运行在UDP上,这样不需要握手,减少服务器的处理时间与负载。使用53号端口。

主机别名
主机设备有着个非常符合URL规范的命名,这个规范的主机名不好记忆,所以也存在便于记忆的别名,访问别名时,也期望的是访问这个主机。
当应用程序访问的是别名时,通过DNS的客户端可以获得规范主机名与对应的IP地址。
负载分配
对于一个网址/IP地址 可以由横夺态不同地区不同地点,不同型号的服务器为其提供服务,DNS可以根据实际情况来决定,你想要访问的网址,到底由哪台服务器为你提供服务。
比如说,当人多的时候,就会给你分配远一点的服务器为你提供服务,人少的时候,就会决定让你家附近的缓存服务器为你提供服务...
DNS域名结构
DNS采用层次树状结构进行命名

域的划分是逻辑上,而不是物理上的。
同一个域名下的两台主机,可以在不同的网络、地区、甚至国家中。
也可能两台相邻的主机是分别属于两个顶级域名下的。
DNS的工作机理
最简单的DNS模型是,只有唯一一台DNS服务器,所有的域名解析请求都需要访问这台服务器,会存在各种各样的问题。
- 单点故障:如果这台DNS服务器奔溃后,整个因特网都将无法奔溃,无法进行域名解析、服务器选择、负载均衡...
- 通信容量:单个DNS服务器得处理上千亿甚至万亿级别的HTTP报文以及邮件报文。
- 远距离造成的延时:这个台唯一的DNS服务器放在那里都会存在地球的另外一边想要访问时会出现非常严重的延迟
- 维护成本:单个DNS服务器对于每时每刻增减的IP-域名解析需要非常庞大的中央数据库来维护
分布式、层次数据库
部分层次结构,下面还有更庞大的细分DNS服务器

根服务器

顶级域服务器

由一些公司维护,任何人都可以申请挂靠在这个顶级域下
权威域服务器
主要是一些组织机构使用的,用于管理维护自己网络服务器。

本地DNS代理服务器查询
从一台主机想要访问某个地址,则首先需要通过访问本地DNS,通过本地DNS服务器代理,去根服务器获取目标IP的顶级域服务器,然后拿到顶级域服务器的IP后,去请求顶级域服务器去查找,挂靠在顶级域下的某个网址,通过网址的欧胡追逐层解析,拿到顶级域下的权威域服务器的名字,向权威与服务器请求后,可以获得权威域服务器的IP,本地DNS服务器,在去权威域服务器请求查找后面的网址,就可以获得目标IP,然后把目标IP返回给请求主机
从请求的网址,从后往前,依次去查询 域的DNS服务器,直到查到权威服务器后,在权威服务器中查到想要的主机。
这个请求查询的过程中,一共有8次的报文请求,从根服务器一路访问到权威服务器。
这种是迭代查询的模式

递归查询的模式

两者需要的报文数都差不多,只不过负载较大的服务器不同,递归查询模式,根服务器的负载应该是最大的,基本上全世界的流量都得从根服务器这里过,且根服务器还得去发送请求,向下查询。
迭代模式将服务器的负载放到了本地DNS服务器上,由本地DNS来处理向下查询。
DNS缓存
为了避免大量数据报文在因特网上流动,减少延时与DNS报文数。因为本地DNS服务器与其它层次服务器请求是要走因特网的。
DNS服务器会将获得的IP域名转换缓存在本地中,当再次需要访问时,就直接从本地回应,不用再次请求别的DNS服务器了
第一次对于跟根服务器的访问,得到的回应不就是那一些顶级域的服务器的IP吗?这样可以i直接存在缓存中,避免总数访问跟服务器,虽然子各个地球都有跟服务器的镜像,但是访问的数量太多了,还是会造成流量强度价太高,因为服务器的层次越高,访问的频率越高。
这样利用DNS服务器的缓存技术,可以绕开根服务器的请求(根服务器请求的频率太多了,就像Cache一眼给,可以直接命中DNS缓存,不用请求原服务器),可以绕开对顶级域服务器的请求...绕开一些访问频率高的域服务器。缓存技术可以加快访问速率,减少公用因特网中的报文数量。
DNS记录与报文
资源记录
DNS分布式服务器的数据库中,存储的是资源记录
资源记录提供了主机名-IP地址的映射,DNS的每条回答报文中,提供了一条或多条资源记录。
资源记录的模板类型(Name,Value,Type,TTL)
TTL
资源记录在缓存中生存的时间,决定了该资源记录什么时候可以被从缓存中删除。
如果很大,说明记录的时间很长,说明该资源记录是一个权威记录,要被使用的频率很高。
如果不大,说明是个缓存记录,到时间直接删掉(一般两天),有些服务器过一段时间IP会改动,为了数据一致性,防止下次找不到。
Type
资源记录中的Name
与Value
都是由Type
决定的。
- A:主机名与对应IP地址的映射,(Name,Value)=(rely.foo.com,145.37.93.2)
- NS:Name是个域,Value是个知道 该域的主机 的 DNS服务器的主机名(管理这个域的权威服务器),(foo.com, dns.foo.com)
- CNAME:Name是主机的别名,Value是主机的规范名
- MX:Name是个邮件服务器的别名,Value是邮件服务器的规范名
DNS报文
只有两种报文:查询报文和回答报文。查询报文和回答报文有着相同的格式。
标识符:16比特组成,用于匹配发送与回答的报文。
P2P应用
纯P2P的架构
- 没有或者很少由一直运行的服务器,每个节点/端的地位都是对等的(既可以做服务端也可以做客户端)
- 任意端系统可以互相直接通信,不需要过中心服务器
- 节点是间歇上网,每次IP可能会变化。
- 利用节点之间的能力,把运算分散给每一个节点,节点之间相互服务
使用案例:文件分发,流媒体,互联网语音
文件分发的对比
C/S模型
如果是以C/S的模式进行文件的分发,N个用户,每份文件F个比特。
对于服务器而言,服务器需要与每个用户建立逻辑连接,然后上载NF个比特进入因特网,上载速率为u,然后用户各自从因特网以一定的下载速率 d 从因特网下载。所以完成这个任务需要的最少的时间是, max F d m i n , N F u \max {\dfrac{F}{d_{min}},\dfrac{NF}{u}} maxdminF,uNF
用户可以并行的从因特网中下载,但是服务器分别给这些用户上层文件,逻辑上是一一建立的连接,所以是NF个比特的文件。
整个任务的关键部分,在于服务器文件上载到因特网中的耗时,随着申请的用户增加,耗时也是线性增加的。
P2P模型
采用P2P的模式的化,服务器只需要上载一份文件给一个用户,然后用户再上载文件到因特网中,给另外一个用户...然后拥有文件的用户给未拥有文件的用户上传文件,让他们下载...
把时间分散出去了,服务器上传文件的时间 ,用户下载文件的时间 ,所有用户上传文件到因特网上的时间(虽然是点对点传输,但是物理上还是得上传到因特网上,然后沿着路径发送到目标用户)
整个耗时, max F u , F d m i n , N F u + ∑ u i \max {\dfrac{F}{u},\dfrac{F}{d_{min}},\dfrac{NF}{u+\sum u_i}} maxuF,dminF,u+∑uiNF
当然,也可以多个用户给一个用户传送文件中的一部分,这样算是并行传输文件,耗时更短,这样的化,任务的耗时瓶颈就是用户的下载能力了。

P2P模式
集中式目录
有一个中心服务器,用于对于各节点所拥有的文件的目录进行索引查找,向下载某个文件时,需要先去中心服务器请求,然后中心服务器找到后,就会让另一个节点向这个节点建立连接,然后发送文件。
缺点就是,版权问题,单点故障(中心服务器挂了就无法使用了)
完全分布式
去中心化,没有中心服务器,每个节点之间都是对等的,是一个图形结构。
每个节点会与周围节点建立连接。
进行查询时,节点回向所有建立连接的节点进行查询,然后再向一级邻居节点进行周围的节点进行文件目录查询,一层层向下查询出去,直到找到想要的文件,然后反向返回回应报文,然后建立两个节点之间的连接,进行文件传输。变成了图的查找,BFS或者DFS。
问题是,这样需要耗费非常大的资源,万一那个文件大家都没有,就会无穷无尽的查找下去。可以通过一些限制条件,剪枝算法、限制算法进行限制性图搜索。如设置TTL,记录遍历过的节点...
不匀称性(混合式)
每个节点要么属于一个小组中的组员,或者是小组的组长,然后小组与小组通过组长建立连接,组长会负责跟踪组员中的文件目录,小组想查找其它组的文件目录,需要小组组长之间建立连接。
组长是组中的中心服务器,组长与组长之间是对等的。
组内层面是集中式的,组间层面是完全式的。

这些资源都需要被一个哈希表维护起来,一个散列值作为文件的唯一的标示,然后还有文件内容与文件描述(文本)。
用户在检索文件时,实际上是在匹配文件描述(文本)。
请求时,是通过文件的哈希值进行对文件操作。
结构化
节点之间通过IP或者分配哈希值,建立有序的拓扑结构,如环状,树状...
CDN
对于一些占据主要带宽的流媒体应用,需要下载大量的数据,占用大量的下行带宽,比如视频应用
DASH:多媒体流化服务
视频文件内容是在HTTP协议上传输。
客户端根据主机的实际情况,带宽阻塞程度,视频设置、剩余缓存区...诸多因素,选择最合适的视频块向服务器请求。

问题
服务器如何通过网络向上百万用户同时流化视频内容
方案一
选择一个超大的,单个的超级服务器中心
容易出现单点故障,周边网络堵塞,资源浪费...该方法不可拓展
方案二
内容分发网络CDN
全网部署缓存节点、存储服务,就近为用户提供服务,加速访问。
ISP需要向CDN的运营商购买CDN服务器,然后将自己的一些服务、资源,缓存到CDN的服务器上,用户访问时,通过DNS域名解析 ,重定向到就近的CDN服务器上,加速网络服务,缓解流量压力。
这种CDN服务器就是Cache服务器,直接命中高速访问缓存服务器,就不用去原始服务器进行访问。
enter deep
CDN服务商,将很多缓存服务器部署在网络边缘(设备)的接入网中,离用户非常近,可以提供非常优质的服务,但是需要大量的服务器来维护,成本很高
bring home
将CDN服务器部署在上层ISP的网络的关键节点处,然后通过线路,将服务器群连接起来。虽然离用户比较远,但是位于网络的关键节点处,还是可以提供较好的服务。
工作流程
- ISP需要先将一些内容拷贝到CDN服务器中
- 当用户请求服务时,通过DNS重定向到最近的CDN服务器,请求内容。
CDN主要是在协议栈的应用层 ,网络结构的网络边缘上进行网络加速的服务。
Socket编程
应用层进程通过访问Socket API来访问传输服务。
TCP
工作流程
- 服务器会先启动,创建一个套接字,把本地的IP与PORT绑定,作为一个欢迎套接字。
- 服务器的执行流会一直在 欢迎套接字 中等待新的TCP连接的请求,所有的TCP连接请求都要从欢迎套接字中获取,如果一直没有,执行流就会阻塞在等待中。
- 客户端启动创建本地的套接字,默认会捆绑一个本地的没有使用的端口。
- 客户端指定一个服务器的IP与端口号(通过DNS解析得到的),然后进行连接
connect
,如果服务器不同意连接,客户端的执行流也会阻塞在这个连接中,直到服务端同意连接。 - 当服务器接收到客户端的请求后,解除阻塞式等待,返回一个新的套接字
connection socket
,该套接字会捆绑客户端IP与PORT和服务端IP与PORT,服务端可以通过这个socket与客户端进行通信。 - 当连接结束后,这个
conection socket
就会被关掉,然后welcome socket
依然在服务端等待请求。
数据结构
IP地址与PORT捆绑关系的数据结构
应用进程,标示本地的端节点,所有的通信、操作都是通过对这个端节点进行操作。

域名和IP地址的数据结构
该结构体对象,是用于调用域名解析 时的参数,返回后,将该对象的IP地址拷贝到sockaddr_in
的IP
部分。

一个端口可以被多个任务/套接字使用,只要套接字不一样,从这个端口进行来报文就可以被分别识别。
UDP
在服务端与客户端之间没有连接,不需要握手。
发送端在每一个报文中都必须指明一个目标IP与端口。
发送的数据可能会乱序,也可能会丢失。
接收端需要从收到的报文中解析处发送端的IP与端口。

总结
应用程序体系架构
- C/S模式
- P2P模式
- 混合模式
衡量应用程序服务性能的指标
- 可靠性
- 带宽
- 延时
- 安全
因特网传输层协议
- 面向连接,可靠的服务 TCP协议
- 无连接、不可靠的数据报 UDP协议
流行的应用层协议
- HTTP
- SMTP,POP3,IMAP
- FTP
- DNS
Socket实现逻辑
- TCP
- UCP