计算机网络持续学习中~
记录一下自己在黑皮书中的学习记录下有用的部分
非常好的学习HTTP RESTFUL API 链接
链接1: https://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html
链接2: https://www.ruanyifeng.com/blog/2016/08/http.html
链接3: https://florimond.dev/en/posts/2018/08/restful-api-design-13-best-practices-to-make-your-users-happy
应用层
2.1应用层协议原理:
Web应用程序中两个互相通讯的不同程序:
- 运行在用户主机上浏览器程序
- 运行在Web服务器主机上
网络上的核心设备并不在应用层起作用, 这将应用软件限制在了端系统,这促进了大量网络应用程序的迅速研发与部署
2.1.1网络应用程序体系结构
应用层的体系结构 明显 不同于网络的体系结构(网络的体系结构是固定的,提供了特定的服务集合)
应用层体系结构(大体两个):
- 客户-服务器体系结构
- p2p体系结构
1.客户-服务器体系结构:
有一个总打开的主机被称为:服务器(它服务于许多其他称为客户的主机请求)
例子:
Web应用服务器:(Web服务器服务于浏览器(运行在客户机)的请求)
在这个体系结构中 客户之间并不直接通信 而是 客户通过向该服务器的ip地址发送分组 用来取得联系
著名的Web应用:
Web FTP Telent 电子邮箱
在这个体系中 如果只有一台服务器 在某些情况(大量的所有请i去)会导致服务器变得不堪重负,因此-配备大量主机的 数据中心
流行的因特网服务:
搜索引擎(Google,bing,百度)等 应用了一个或多个数据中心(1个数据中心 可以有数十万台服务器)
2. p2p体系结构
主机对之间使用直接通信(对等方),引人入胜的特性(自扩展性),
面临挑战: 高度非集中式,面临安全性,性能和可靠性等挑战
应用:
文件共享,对等方协助下载器(迅雷)因特网电话和视频会议
有的应用具有两种的混合体系: 服务器被用来跟踪用户的ip地址 但 用户到用户的报文在用户到主机之间 直接发送
2.1.2进程通信
运行在多个端系统上的程序如何互相通信,进行通信实际上是进程而不是程序
进程可以被认为是运行在端系统的一个程序。 多个进程运行在相同的端系统时使用进程间通信机制互相通信(通信规则由 _端系统上的操作系统制定_)
关注的是 运行在不同端系统上的进程间的通信
在不同的端系统上的进程 通过 跨越进程通过网络互相发送报文
发送进程 生成并 向网络中 发送报文 -》接收进程接收报文并通过回送报文响应
1.客户和服务器进程
网络应用程序由 成对的进程组成 进程之间 通过网路互相发送报文
例子:
客户浏览器进程 与 Web服务器进程交换报文 在p2p中: 文件从一个对等方中的进程 传输到 另一个对等放进程 其中一个进程被表示为客户 另一个进程被标记为服务器
2.进程与计算机网络之间的接口(api)
进程 通过一个称为套接字(socket) 的软件接口 向网络发送报文和从网络接收报文
套接字: 是同一台主机被应用层与传输层之间的接口 套接字被称为 应用进程 和 网络之间的(api)
我们可以控制套接字在应用端的一切 但是 对运输层几乎没有控制权 仅限于:选择运输层协议 也能设定几个运输层协议(最大缓存,最大报文长度)
3.进程寻址
主机由ip地址标识, ip地址: 是32比特的量它能够标识该主机
端口号: 众所周知的端口号列表: http://www.iana.org
2.1.3 可供应用程序使用的运输服务
运输层协议负责从接收进程的套接字得到该报文 开发应用时还要选择根基情况 选择合适的协议 选择服务
服务: 可靠数据传输 吞吐量 定时 安全性
1.可靠数据传输
因为 分组可能在计算机网络中丢失,
例子:
分组能够使路由器中的缓存溢出, 分组中的某些比特损坏后可能被丢弃 在某些特定情况下: 电子邮件,文件传输,远程主机访问
如果数据丢失可能会造成灾难性的损失,
因此 当运输层协议提供一种可靠传输, 发送进程只需要将数据传递到套接字中 就可以完全相信数据无差别的到达接收进程
但是也有一些东西可以容忍数据的丢失(不适用可靠数据传输时) 音频/视频
2.吞吐量
吞吐量就是发送进程能够向接收进程交付比特的速率 会话 将共享沿着网络路径的带宽 运输层协议能够确保可用吞吐量为至少r/bit/s当(应用程序请求r/bit/s)
示例:
电话需要固定的bit进行编码 如果不能提供这中吞吐量或者较小 造成放弃发送(因为接收一半可能是没用的)
弹性应用:可以根据 可用的宽带或多或少来利用可供使用的吞吐量
当然 吞吐量越高越好哈哈哈
3.定时
运输层协议也能提供定时保证 因为在特定情况下 电话,虚拟环境 多方游戏(对时间有严格的限制) 否则会造成停顿, 较长的时延
但 端到端的时延没有严格的约束
4,安全性
运输协议为应用提供 一种或多种安全性服务 能加密发送进程传输的所有数据 防止数据以某种方式 在两个进程之间被观察
2.1.4 因特网提供的运输服务
因特网(TCp/IP网络)为应用程序提供两个运输层协议(TCP/UDP)
1.TCP服务
特点: 面向连接服务和可靠数据传输服务
面向连接: 在应用层数据报文开始流动之前, TCP使 客户 和 服务器 之前相互交换 运输层控制信息(握手过程) 让它们提前做好准备
握手之后 TCP连接就建立了 连接时双工的: 双方可以连接上 同时进行报文的收发 当收发结束后 必须拆除连接
可靠的数据传送服务: 通信进程依靠TCP 无差错的按照顺序交付所有的发送数据 当一方将字节流传入套接字时 依靠TCP将相同的
字节流交付给接收方的套接字 没有字节的丢失和冗余
TCP具有拥塞控制机制 当发送方和接收方之间网络出现问题堵塞 TCP的机制可以抑制发送进程 也试图限制每个TCP连接 达到公平共享网络宽带目的
原文链接: https://github.com/wolverinn/Waking-Up/blob/master/Computertree-way-handshake
简单理解:
三次握手(三报文握手)
第一次握手:Client将SYN置1,随机产生一个初始序列号seq发送给Server,进入SYN_SENT状态;
第二次握手:Server收到Client的SYN=1之后,知道客户端请求建立连接,将自己的SYN置1,ACK置1,产生一个acknowledge number=sequence number+1,并随机产生一个自己的初始序列号,发送给客户端;进入SYN_RCVD状态;
第三次握手:客户端检查acknowledge number是否为序列号+1,ACK是否为1,检查正确之后将自己的ACK置为1,产生一个acknowledge number=服务器发的序列号+1,发送给服务器;进入ESTABLISHED状态;服务器检查ACK为1和acknowledge number为序列号+1之后,也进入ESTABLISHED状态;完成三次握手,连接建立。
目的: 建立 TCP连接
两次握手呢?
只发送前两次报文 不会有 最后一次的客户端同步状态报文
这就会导致超时重传
把问题想象成发送报文就好理解了:
一段时间后,之前滞留在网络中的那个失效的TCP连接请求报文段到达了TCP服务器进程,TCP 服务器进程会误认为这是TCP客户进程又发起了一个新的TCP连接请求,于是给TCP客户进程发送TCP连接请求确认报文段并进入连接已建立状态。
该报文段到达TCP客户进程,由于TCP客户进程并没有发起新的TCP连接请求,并且处于关闭状态,因此不会理会该报文段。
不可以!
如果不是用三次握手 那么只要client发出确认报文段, server发出确认新的连接就建立了
因为第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了延误到连接释放以后的某个时间才到达
但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。
四次握手?
可以。但是会降低传输的效率。
四次握手是指:第二次握手:Server只发送ACK和acknowledge number;而Server的SYN和初始序列号在第三次握手时发送;
原来协议中的第三次握手变为第四次握手。出于优化目的,四次握手中的二、三可以合并。
了解名词ACK acknowledge number SYN 初始序列号
参考链接: https://juejin.cn/post/7028003193502040072
确认标志位ACK: 取值为1时确认号字段才有效;取值为0时确认号字段无效。TCP规定,在连接建立后所有传送的TCP报文段都必须把ACK置1。
源端口:16bit 目的端口: 16bit
序号:32bit
同步标志位SYN: 在TCP连接建立时用来同步序号。终止标志位FIN: 用来释放TCP连接。复位标志位RST: 用来复位TCP连接。
推送标志位PSH: 接收方的TCP收到该标志位为1的报文段会尽快上交应用进程,而不必等到接收缓存都填满后再向上交付。
TCP建立需要解决的问题:
1、使TCP双方能够确知对方的存在 。
2、使TCP双方能够协商一些参数( 最大窗口值是否使用窗口扩大选项和时间戳选项,以及服务质量等)。
3、使TCP双方能够对运输实体资源(例如缓存大小连接表中的项目等)进行分配。
TCP规定SYN被设置为1的报文段不能携带数据但要消耗掉一个序号。
TCP服务器进程收到TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并进入同步已接收状态
总结:
如果没有第三次握手告诉服务器客户端能否收到服务器传输的数据的话,
服务器端的端口就会一直开着,等到客户端因超时重新发出请求时,服务器就会重新开启一个端口连接。长此以往, 这样的端口越来越多,就会造成服务器开销的浪费。
探测报文检测 确认客户端是否出现故障 然后关闭连接
四次挥手
第一次挥手:Client将FIN置为1,发送一个序列号seq给Server;进入FIN_WAIT_1状态;
第二次挥手:Server收到FIN之后,发送一个ACK=1,acknowledge number=收到的序列号+1;进入CLOSE_WAIT状态。此时客户端已经没有要发送的数据了,但仍可以接受服务器发来的数据。
第三次挥手:Server将FIN置1,发送一个序列号给Client;进入LAST_ACK状态;
第四次挥手:Client收到服务器的FIN后,进入TIME_WAIT状态;接着将ACK置1,发送一个acknowledge number=序列号+1给服务器;服务器收到后,确认acknowledge number后,变为CLOSED状态,不再向客户端发送数据。客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。完成四次挥手。
还有些不太理解学习一下这些名字之后再来理解
2.UDP服务
UDP是 轻量级运输协议仅提供最小服务 状态:无连接的,两个进程通信没有握手过程, 提供:不可靠传输协议:不保证报文到达接收进程
报文也可能是乱序到达 也没有拥塞控制机制
因特网运输协议所不提供的服务
TCP在应用层 用SSL加强提供安全服务 漏掉了 吞吐量,和定时保证
2.1.5 应用层协议
定义了:
- 交换的报文类型 如:请求报文,响应报文
- 报文类型语法 如:报文字段是如何描述的
- 字段的语义 就是信息含义
- 确定进程何时发送报文
Web的应用层协议是HTTP:
因特网电子邮件应用:包括 电子邮件报文结构的标准 以及 定义报文如何在服务器之间以及如何在服务器与邮件客户程序之间传递的应用层协议
2.2Web和HTTP
2.2.1HTTP概况
Web层应用层协议是超文本传输协议 HTTP由两个程序实现(客户程序)(服务器程序) 通过交换HTTP报文进行会话
Web界面
它是由文档组成的也就是(对象): 一个对象是一个文件 例如: HTML文件 JPEG图形
例如: 如果一个HTML文件+五个图片 也就是 Web页面有6个对象
URL地址两部分组成:服务器主机名 和 对象 URL:http://www/someSchool.edu/someDepartment/picture.gif 到edu是主机名
后面是路径名
Web服务器 实现了HTTP服务器端 用于存储Web对象 流行的Web服务器:Apache等
2.2.2非持续连接和持续链接
两个问题:
每个请求/响应是 经 一个单独的TCP连接: 这称为(非持续连接)
还是 经相同的TCP连接发送: 这称为(持续链接)
1.采用非持续连接的HTTP
过程:
每个TCP只传输一个请求报文和一个响应报文
串行TCP:
并行TCP:
浏览器可以设置并行数 如果设为1 那么就会变化串行连接 并行连接可以减少响应时间
往返时间(RTT)
RTT包括: 分组传播时延 分组在(中间路由器)(交换机)的排队时延 分组时延
三次握手过程
- 客户向服务器发送小TCP报文
- 服务器用小TCP报文做出确认和响应
- 客户向服务器返回确认
这三次握手中 前两部分花费 一个RTT
握手后向该TCP连接发送HTTP请求报文 一旦请求报文到达服务器 服务器就在TCP连接上发送HTML文件
该HTTP的请求和响应用了一个HTTP 服务器传输HTML花费了时间
一共为 2RTT+传输时间
2.采用持续连接的HTTP
非持续链接的缺点: 每次连接都需要: 分配TCP缓存区和保持TCP变量 这给Web服务器造成了很大的负担
每一个对象都会造成上面的时延时间
HTTP1.1 在服务器响应后 保持TCP打开 用单个TCP进行传送 在一定的时间间隔没有被使用HTTP服务器再关闭连接
HTTP2 它允许再相同连接中多个请求和回答错误 增加了连接中优化HTTP报文请i去和回答机制
2.2.3 HTTP请求报文格式
1.HTTP 请求报文
1 | GET /somedir/page.html HTTP/1.1 |
第一行:请求行
后继行:首部行
2.HTTP 响应报文
真实的HTTP响应报文:
用Telnet 登录到喜欢的Web服务器上 请求报文请求放在该服务器上的某些对象
1 |
|
这里的
GET /kurose_ross/interactive/index.php HTTP/1.1
Host: gaia.cs.umass.edu
格式很重要 回车必不可少
只想看HTTP协议的报文行 用HEAD代替GET
上述简短的两行代码 打开了主机 .edu的80端口的TCP连接 发送了一个HTTP请求报文
1 | telnet gaia.cs.umass.edu 80 |
插入
GT方法就是安全且幂等的,因为它是「只读」操作,无论操作多少次,服务器上的数据都是安全的,
且每次的结果都是相同的。所以,可以对GET请求的数据做缓存,这个缓存可以做到浏览器本身上
(彻底避免浏览器发请求),也可以做到代理上(如gix),而且在浏览器中GET请求可以保存为书
签。
POST因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据
就会创建多个资源,所以不是幂等的。所以,浏览器一般不会缓存POST请求,也不能把POST请求保
存为书签。
减少HTTP请求次数
1.减少重定向请求次数
重定向请求越多,那么客户端就要多次发起 HTTP 请求 每一次的 HTTP 请求都得经过网络,这无疑会越降低网络性能
重定向的工作交由代理服务器完成,就能减少 HTTP 请求次数了
代理服务器知晓了重定向规则后,可以进一步减少消息传递次数
2.2.4用户与服务器的交互 cookie
HTTP服务器是无状态的 不需要验证。但是站点是希望能够标识用户, 因为服务器可能需要限制用户的访问,这就需要把内容和用户关联到一起
HTTP使用了 cookie
cookie的四个组件
- HTTP响应报文的一个cookie首部行
- HTTP请求报文的一个cookie首部行
- 用户端系统保留一个cookie文件浏览器进行管理
- 位于WEB站点的后端数据库
这样当Susan再次访问一个站点的时候 浏览器放入首部行 就不用再输入一些信息了
实行了”点击购物“
2.2.5 Web缓存
还需要 深入理解缓存器带来的好处
HTTP中的 强制缓存和协商缓存
强制缓存定义:
强制缓存是指客户端直接使用本地缓存的数据,而不会向服务器发送请求验证数据的有效性。
工作方式:
HTTP 头部中:
使用 Cache-Control 指定缓存策略(例如 max-age)。
或使用 Expires(HTTP/1.0,已逐步被 Cache-Control 替代)指定缓存失效时间。
如果缓存未过期,浏览器会直接从本地缓存读取数据,而不会与服务器通信。
特点:
节约资源:不需要请求服务器。
时效性:受 max-age 或 Expires 的约束,可能存在缓存失效时间的误差。
协商缓存 (Conditional Cache)
定义: 协商缓存是指客户端向服务器发送请求,验证本地缓存是否有效。如果有效,服务器返回一个状态码(如 304 Not Modified),客户端可以继续使用本地缓存的数据;否则,服务器返回最新的数据。
工作方式:
HTTP 头部中:
请求头:使用 If-Modified-Since 或 If-None-Match。
响应头:服务器返回 Last-Modified(表示资源最后修改时间)或 ETag(资源的唯一标识符)。
客户端会将缓存中记录的 ETag 或 Last-Modified 发送到服务器进行验证:
如果验证通过(服务器认为缓存未修改),返回 304。
如果验证失败(资源已更新),返回新的资源数据(200 OK)。
特点:
相对准确:确保缓存数据的有效性。
需要通信:每次都需要向服务器发送请求进行验证。
缓存命中率
内容分发网络(CDN):多个共享CDN 专用CDN
条件GET方法
问题: 存放在混村其中的对象副本是旧的,或者再保存到服务器中的对象再缓存到客户上之后 就被修改了
HTTP协议机制: 允许缓存器证实它的对象是最新的 也就是(条件GET)
If-modified-since: Wed, 9 Sep 2015 09:23:24
”If-Modified-Since“首部行 这个请求报文就是条件GET请求报文
缓存器在存储对象的同时也存储了最后的修改日期 缓存器通过一个条件GET执行最新查询
这条语句告诉服务器 仅当指定日期后该对象被修改过 才发送对象
如果没有修改过 则相应的时候没有body 因为再次返回一样的body会浪费宽带
插入
数据流
在实践中,客户端指定数据流的优先级通常是在使用 HTTP/2 时实现的。HTTP/2 引入了流优先级(Stream Priority)机制,允许客户端为每个流指定一个优先级值,这个值会影响服务器在资源争用时对请求的处理顺序。
流优先级机制
优先级参数:每个 HTTP/2 流都可以有一个权重值(weight),范围是 1 到 256,数字越大,优先级越高。
依赖关系:每个流还可以声明依赖于另一个流(dependency)。如果一个流依赖于另一个流,服务器会优先完成被依赖的流。
服务器根据这些参数决定如何分配带宽和计算资源。
实现流优先级的例子
客户端的实现(使用 cURL)
我们可以用支持 HTTP/2 的工具,如 curl,来演示流优先级的使用。
发送两个并发请求(模拟流)
curl –http2 -o output1.html https://example.com/slow-response &
curl –http2 -o output2.html https://example.com/fast-response &
wait
默认情况下,这两个流的优先级相同,服务器会尽力均匀分配资源来处理它们。
设置优先级 使用 –http2-prioritize 选项来设置优先级。例如:
curl –http2 –http2-prioritize-weight 256 -o fast.html https://example.com/fast-response &
curl –http2 –http2-prioritize-weight 1 -o slow.html https://example.com/slow-response &
wait
这里:
fast-response 的优先级为 256(最高)。
slow-response 的优先级为 1(最低)。
服务器会优先响应 fast-response 流。
2.3 因特网中的电子邮件
3个主体组成部分 用户代理 邮件服务器 简单邮件传输协议
SMTP: 应用层协议 使用TCP可靠数据传输 每台邮件服务器上:既运行SMTP的客户端也运行SMTP的服务器端
因为:
SMTP发送邮件的时候 表现为: 客户端
SMTP接收邮件的时候 表现为: 服务器端
使用7bit ASCII标识
2.3.1 SMTP
12.18 日
套接字编程:
UDP套接字:
TCP套接字