赞
踩
网络协议指的是计算机网络中互相通信的对等实体之间交换信息时所必须遵守的规则的集合。
为了增强通用性和兼容性,计算机网络都被设计成 层次机构,每一层都遵守一定的规则
协议
TCP 是面向连接的、可靠的、基于字节流的传输层通信协议
为什么需要TCP
序列号 : 在建立连接时由计算机生成的 随机数 作为初始值,通过 SYN 包传给接收端主机,每发送一次数据,就 【累加】**【数据字节数】**的大小。 用来解决网络包乱序问题
确认应答号 : 指下一次【期望】收到的 数据的序列号 ,发送端 收到 这个 确认应答 以后可以认为在这个序号以前的数据都已经被正常接收。用来解决不丢包的问题
控制位 :
SYN :该位为 1 时,表示希望建议连接,并在 系列号 的字段进行初始化
ACK : 该位为 1 时,【确认应答】的字段变为有效,TCP规定除了最初建立连接时的 SYN 包之外该位必须设置为 1
RST : 该位为 1 时, 表示TCP连接中出现 异常 必须 强制断开连接
FIN :该位为 1 时,希望断开连接。当通信结束希望断开连接时,通信双方主机之间就可以相互交换 FIN 位为 1 的TCP段
唯一确定一个TCP连接
TCP四元组可以唯一的确定一个连接
源端口和目标端口的字段 (16位) 是在 TCP头部中,作用是告诉 TCP协议把报文发给哪个进程
源地址和目的地址的字段 (32位) 是在 IP头部中,作用是通过 IP协议发送报文给对方主机
校验和
序列号 / 确认应答号
流量控制
拥塞控制
ARQ协议
超时重传
UDP 不提供复杂的控制机制,利用 IP 提供面向**【无连接】**的通信服务
UDP 头部只有 8 个字节(64位)
UDP头部没有【首部长度】字段,TCP有
TCP有 可变长的【选项】字段,而UDP头部长度则是 不会变化的,无需多一个字段去记录UDP的首部长度
UDP头部有【包长度】字段,而TCP没有
为了网络设备硬件设计和处理方便,首部长度需要是 4 字节的整数倍
TCP 和 UDP 区别
1. 连接
2. 服务对象
3. 可靠性
4. 拥塞控制、流量控制
5. 首部开销
6. 传输方式
7. 分片不同
应用场景
TCP是 面向连接,能保证数据的可靠性交付
UDP是 面向无连接,可以随时发送数据,再加上UDP本身的处理即简单又高效
TCP 是面向连接的协议,所以使用TCP前必须先建立连接,而建立连接是通过三次握手来进行的
客户端和服务端都处于 关闭 状态。 先是 服务端 主动监听某个端口,处于 监听 状态
1.客户端会随机初始化序号(client_isn),将其置于TCP首部的**【序列号】字段中,同时把 SYN 标志位 置为 1。 接着把第一个SYN报文**发送给服务端,表示向服务端发起连接,该报文 不包含应用层数据,之后客户端处于 SYN-SENT 状态
2. 服务端收到客户端的 SYN 报文后,也随机初始化自己的序号(server_isn),将此序号填入TCP首部的**【序列号】字段中,其次把TCP首部的【确认应答号】**字段填入 client_isn + 1,接着把 SYN 和 ACK 标志位置为 1。最后把报文发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN-RCVD状态
3.客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文TCP首部 ACK 标志位置为 1,其次**【确认应答号】字段填入 server_isn + 1,最后把报文发送给服务端,这次报文可以携带客户端到服务器的数据**,之后客户端处于 ESTABLISHED 状态
服务器收到客户端的应答报文后,也进入 ESTABLISHED 状态
一旦完成三次握手,双方都处于 ESTABLISHED 状态,此时连接就已建立完成,客户端和服务端就可以相互发送数据了 (第三次握手是可以携带数据的,前两次握手是不可以携带数据的)
【两次握手】: 无法防止历史连接的建立,也无法可靠的同步双方序列号,会造成双方资源的浪费,
【四次握手】 : 三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数
为什么三次握手才可以初始化Socket、序列号和窗口大小并建立TCP连接
序列号能够保证数据包不重复、不丢弃和按序传输
原因一:避免历史连接
在 网络拥堵 情况下,客户端连续发送多次 SYN 建立连接的报文,一个【旧SYN报文】比【最新的SYN】报文早到达了服务端
原因二 :同步双方初始序列号
TCP协议的通信双方,都必须维护一个**【序列号】,序列号是可靠传输**的一个关键因素
当客户端发送携带**【初始序列号】的 SYN 报文的时候,需要服务端回一个 ACK 应答报文,表示客户端的SYN报文已被服务端成功接收,那当服务端发送【初始序列号】**给客户端的时候,依然也要得到客户端的应答回应。这样才能确保双方的初始序列号能被可靠的同步
原因三 :避免资源浪费
只有**【两次握手】**,当客户端的 SYN 请求连接在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN, 由于没有第三次握手, 服务器不清楚客户端是否收到了自己发送的建立连接的 ACK 确认信号,所以每收到一个 SYN 就只能先主动建立一个连接,这会造成什么情况呢?
如果客户端的 SYN 阻塞了,重复发送多次 SYN 报文,那么服务器在收到请求会 建立多个冗余的无效链接,造成不必要的资源浪费
1. 客户端打算关闭连接,会向服务端发送一个 TCP 首部 FIN 标志位 被置为 1 的报文,之后进入 FIN_WAIT_1 状态
**2.**服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSED_WAIT 状态
客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态
3.等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态
**4.**客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
服务器收到了 ACK 应答报文后,就进入了 CLOSED 状态,至此服务端已经完成连接的关闭
客户端在经过 2MSL 一段时间后,自动进入 CLOSED 状态,至此客户端也完成连接的关闭
每个方向都需要 一个FIN和一个ACK,因为通常被称为 四次挥手
主动关闭连接的,才有 TIME_WAIT 状态
服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都会分开发送,从而比三次握手导致多了一次
如果最后一次挥手出现丢包,客户端最后回复的ACK丢了
为什么需要TIME_WAIT状态
主动发起关闭连接的一方,才会有 TIME_WAIT 状态
TIME_WAIT等待足够长的情况能够遇到两种情况:
客户端在 TIME_WAIT 状态等待 2MSL 时间后,就可以 保证双方的连接都可以正常的关闭
为什么TIME_WAIT等待的时间是 2MSL?
MSL是什么
MSL 是 报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为 TCP 报文基于是 IP协议 的,而 IP头中有一个 TTL 字段,是IP数据报可以经过的最大路由数,每经过一个处理它的路由器此值就 减 1,当此值为 0 则数据报将被丢弃,同时发送 ICMP 报文通知 源主机
MSL 与 TTL 的区别
MSL 的单位是时间,而 TTL 是经过路由跳数
MSL 应该要大于等于 TTL 消耗为0的时间,以确保报文已被自然消亡
TIME_WAIT 等待2倍的 MSL
网络中可能存在来自发送方的数据包,当这些数据包被接受方处理后又会向对方发送响应,所以 一来一回需要等待 2 倍的时间
2MSL 的时间是从 客户端接受到FIN后发送ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK 没有传输到服务端,客户端又接受到了服务端重发的 FIN 报文,那么 2MSL 时间将重新计时
在Linux系统里 2MSL 默认是 60 秒,那么一个 MSL 也就是 30 秒。 Linux系统停留在 TIME_WAIT的时间为固定的 60 秒
如果要修改 TIME_WAIT 的时间长度,只能修改 Linux 内核代码里 TCP_TIMEWAIT_LEN的值,并重新编译 Linux 内核
TIME_WAIT过多有什么危害?
过多的 TIME-WAIT 状态主要的危害有两种:
如果发起连接一方的 TIME_WAIT 状态过多,占满了所有端口资源,则会导致无法创建新连接
客户端受端口资源限制:
服务端受系统资源限制:
如何优化 TIME_WAIT?
net.ipv4.tcp_tw_reuse 和 tcp_timestamps
如果一个已经失效的连接被重用了,但是该旧连接的历史报文还残留在网络中
TCP每发送一个数据,都要进行一次确认应答。当上一个数据包收到且应答了,再发送下一个。这样的传输方式有一个缺点 : 数据包的往返时间越长,通信的效率就越低
TCP引入了 窗口 这个概念,可以指定窗口大小,窗口大小指 无需等待确认应答,就可以继续发送数据的最大值
**实现: **
操作系统开辟的一个缓存空间,发送方主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除
假设窗口大小为 3 个 TCP段,那么发送方就可以**【连续发送】** 3 个 TCP段,并且中途若有ACK丢失,可以通过**【下一个确认应答进行确认】**
图中的 ACK 600 确认应答报文丢失,也没关系,因为可以通过下一个确认应答进行确认,只要发送方收到了 ACK 700 确认应答,说明 700 以前的所有数据 【接收方】都收到了。这个模式就叫 累计确认 或者 累计应答
窗口大小由哪一方决定?
TCP头里有一个字段叫 Window,也就是窗口大小
这个字段是接受方告诉发送方自己还有多少缓冲区可以接收数据。于是发送方就可以根据这个接收方的处理能力来发送数据,而不会导致接收方处理不过来
通常窗口的大小是由接收方的窗口大小来决定的
发送方发送的数据大小 不能超过 接收方的窗口大小,否则接受方就无法正常接收到数据
接收窗口和发送窗口的大小是相等的吗?
发送方的滑动窗口
下图为发送方缓存的数据,根据处理的情况分为四个部分,其中深蓝色方框是发送窗口,紫色方框是可用窗口
当发送方把数据【全部】都一下发送出后后,可用窗口大小就为 0 了,表明可用窗口耗尽,在没收到 ACK 确认之前是无法继续发送数据了
当收到之前发送的数据 32~36 字节的 ACK 确认应答后,如果发送窗口的大小没有变化,则滑动窗口往右边移动5个字节,因为有5个字节的数据被应答确认,接下来 52 ~ 56 字节又变成了可用窗口,那么后续也就可以发送 52 ~ 56 这5个字节的数据了
接收方的滑动窗口
其中三个接收部分,使用两个指针进行划分:
TCP滑动窗口方案使用三个指针来跟踪在四个传输类别中的每一个类别中的字节。其中两个指针是绝对指针(指特定的序列号),一个是相对指针(需要做偏移)
可用窗口大小的计算 = SND.WND - (SND.NXT - SND.UNA)
如果一直发数据给对方,但对方处理不过来,那么就会导致触发重发机制,从而导致网络流量的无端的浪费
流量控制 : TCP提供了一种机制可以让【发送方】 根据 【接收方】的 实际接受能力控制发送的数据量
SND.UNA:绝对指针,指向的是已发送但未收到确认的第一个字节的序列号
SND.NXT :绝对指针,指向的是已发送但未收到确认的第一个字节的序列号
RVC.NXT:指针,指向期望从发送方发送来的下一个数据字节的序列号
假设以下场景: 客户端是接收方,服务端是发送方,接受窗口和发送窗口都为 200,假设两个设备在整个传输过程中都保持相同的窗口大小,不受外界影响(流量控制的过程)
实际上,发送窗口和接受窗口中所存放的字节数,都是放在操作系统内存缓冲区中的,而操作系统的缓冲区,会被操作系统调整
当应用程度没有及时读取缓存时,发送窗口和接受窗口的变化
说明过程:
最后窗口都收缩为0,也就是发生了窗口关闭。当发送方可用窗口变为 0 时,发送方实际上会定时发送窗口探测报文,以便知道接收方的窗口是否发生了改变
当服务端系统资源非常紧张的时候
操作系统可能会直接减少了接受缓冲区大小,这时应用程序又无法及时读取缓存数据,会出现数据包丢失的现象
如果发生了先减少缓存,再收缩窗口,就会出现丢包的现象
为了防止这种情况,TCP规定是不允许同时减少缓存又收缩窗口,而是采用先收缩窗口,过段时间再减少缓存,这样可以避免了丢包的情况
TCP 通过让接收方指明希望从发送方接收的数据大小 (窗口大小) 来进行流量控制
如果窗口大小为 0 时,就会阻止发送方给接收方传递数据,直到窗口变为非 0 为止,这就是窗口关闭
窗口关闭潜在的危险
接收方向发送方通告窗口大小时,是通过 ACK 报文来通告的
TCP如何解决窗口关闭时,潜在的死锁现象
TCP 为每个连接设有一个持续定时器,只要 TCP 连接一方收到对方的零窗口通知,就启动持续计时器
如果持续计时器超时,就会发送 窗口探测报文,而对方在确认这个探测报文时,给出自己现在的接收窗口大小
窗口探测的次数一般为 3 次,每次大约 30 - 60 秒(不同的实现可能会不一样)。如果 3 次过后接收窗口还是 0 的话,有的 TCP 实现就会发 RST 报文来中断连接
在网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包时延、丢失等,这时TCP就回重传数据,但是一重传就会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这个情况就会进入恶性循环被不断地放大
当网络发送拥塞时,TCP会自我牺牲,降低发送的数据量,就有了 拥塞控制,控制的目的就是 避免【发送方】的数据填满整个网络
为了在【发送方】调节所要发送数据的量,定义了一个叫做 【拥塞窗口】 的概念
怎么判断当前网络出现了拥塞?
只要 【发送方】没有在规定时间内接收到 ACK 应答报文,也就是 发生了超时重传,就会认为网络出现了拥塞
拥塞窗口 cwnd 是发送方维护的一个的状态变量,它会根据 网络的拥塞程度动态变化的
发送窗口 swnd 和 接收窗口 rwnd 是约等于的关系,那么由于加入了拥塞窗口的概念后,此时发送窗口的值是 swnd = min(cwnd,rwnd),也就是拥塞窗口和接收窗口中的最小值
拥塞窗口 cwnd 变化的规则:
慢启动
假定拥塞窗口 cwnd 和 发送窗口 swnd 相等
慢启动涨到什么时候?
有一个叫慢启动门限 ssthresh 状态变量
拥塞避免算法
接着慢启动的例子, 假定 ssthresh 为 8
拥塞发生
当网络出现拥塞,也就是会发生数据包重传,重传机制主要有两种:
超时重传
快速重传
发生超时重传的拥塞发生算法
当发生了【超时重传】,则就会使用拥塞发生算法
这个时候,ssthresh 和 cwnd 的值会发生变化
接着就重新开始 慢启动, 慢启动是会突然减少数据流的。一旦【超时重传】,马上回到解放前。这种方式太激进了,反应也很强烈,会中造成网络卡顿
发生快速重传的拥塞发生算法
【快速重传算法】。 当接收方发现丢了一个中间包的时候,发送三次前一个包的ACK,于是发送端就会快速地重传,不必等待超时再重传
TCP认为这种情况不严重,因为大部分没丢,只丢了一小部分
快速恢复
进入快速恢复之前, cwnd 和 ssthresh 已被更新了:
进入快速恢复算法如下:
HTTP 是计算机里专门在两点之间传输文字、图片、音频等超文本数据的约定和规范
协议
传输
超文本
URI和URL
HTTP方法
HTTP报文
HTTP报文分为 请求报文 和 响应报文
HTTP报文包括以下三个部分:
若HTTP首部字段重复了会如何
4中HTTP首部字段类型
常见的首部实例
Date:Tue, 30ct 2021 12:00:00 GMT 服务器产生响应的日期
Accept: image/gif,image/jpeg, text/html 客户端可以接受GIF图片和JPEG图片以及HTML
Content-type: image/gif 实体的主体部分的类型
Content-length: 15040 实体的主体部分包含了15040字节的数据
通用首部字段
Cache-Control
操作缓存的工作机制
Cache-Control : private, max-age = 0, no-cache
Cache-Control : public 其他用户也可利用缓存
Cache-Control : private 响应只以特定的用户作为对象
Cache-Control : no-cache 防止从缓存中返回过期的资源
客户端发送的请求中包含表示:客户端将不会接收缓存过的响应
服务端返回的响应中包含表示:缓存服务器不能对资源进行缓存
Cache-Control : no-cache=Location 若报文首部字段Cache-Control中对no-cache字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存
Cache-Control : no-store 表示请求或响应中包含机密信息,则指令规定缓存不能在本地存储请求或响应的任一部分
Cache-Control : max-age=604800(单位:秒)
当客户端发送的请求中包含该指令时,如果判定 缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。若max-age值为0,那么缓存服务器通常需要将请求转发给源服务器
当服务器返回的响应中包含该指令时,缓存服务器将不对资源的有效性再作确认,而max-age数值代表资源保存为缓存的最长时间
Cache-Control : s-maxage=604800 (单位:秒) s-maxage指令的功能和max-age指令的相同,不同点是同一用户重复返回响应的服务器来说,这个指令没有任何作用
Date
创建HTTP报文的日期和时间
Connection
管理持久连接,控制不再转发给代理的首部字段
Connection : close HTTP/1.1版本的默认连接都是持久连接。客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定Connection首部字段的值为Close
Connection : Keep-Alive HTTP/1.1之前的HTTP版本的默认连接都是非持久连接。为此,如果想在旧版本的HTTP协议上维持持续连接,则需要指定Connection首部字段的值为Keep-Alive
Upgrade
用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nlmRUBUS-1649846358944)(D:\TyporaImage\计算机网络 \image-20211015145122246.png)]
Upgrade首部字段产生作用的Upgrade对象仅限于客户端和邻接服务器之间。即使用首部字段Upgrade时,还需要额外指定 Connection:Upgrade
对于附有首部字段Upgrade的请求,服务器可用101 Switching Protocols状态码作为响应返回
请求首部字段
host
请求的资源所处的互联网主机名和端口号,Host首部字段在HTTP/1.1规范内是唯一一个必须被包含在请求内的首部字段
Authorization
告知服务器,用户代理的认证信息。想要通过服务器认证的用户代理会在接收到返回的401状态码响应后,把首部字段Authorization加入请求中。共用缓存在接收到含有Authorization首部字段的请求时的操作处理会略有差异
Accept
通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用type/subtype这种形式,一次指定多种媒体类型
Accpet-Charset
通知服务器,用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字段Accept相同的是可用权重q值来表示相对优先级
Accept-Encoding
通知服务器,用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码
Accept-Language
通知服务器,用户代理能够处理的自然语言集(指中文或英文等),以及自然语言集的相对优先级。可一次指定多种自然语言集
响应首部字段
Accept-Ranges: bytes
告知客户端,服务器是否能处理范围请求,以指定获取服务器端某个部分的资源
可指定的字段值有两种,可处理范围请求时指定其为bytes,反之则指定其为none
Age : 600
告知客户端,服务器在多久前创建了响应。字段值的单位为秒
若创建该响应的服务器是缓存服务器,Age值是指缓存后的响应再次发起认证到认证完成的时间值。代理创建响应时必须加上首部字段Age
ETag : "82e22293907ce725faf67773957acd12"
告知客户端实体标识。将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的ETag值
当资源更新时,ETag值也需要更新。生成ETag值时,并没有统一的算法规则,而仅仅是由服务器来分配
Location
将响应接收方引导至某个与请求URI位置不同的资源。基本上,该字段会配合 3xx:Redirection 的响应,提供重定向的URI
几乎所有的浏览器在接收到包含首部字段Location的响应后,都会强制性地尝试对已提示的重定向资源的访问
Proxy-Authenticate
把由代理服务器所要求的认证信息发送给客户端
它与客户端和服务器之间的HTTP访问认证的行为相似,不同之处在于其认证行为是在客户端与代理之间进行的。而客户端与服务器之间进行认证时,首部字段WWW-Authorization有着相同的作用
WWW-Authenticate
用于HTTP访问认证。它会告知客户端适用于访问请求URI所指定资源的认证方案(Basic或是Digest)和带参数提示的质询(challenge)
状态码401 Unauthorized响应中,肯定带有首部字段WWW-Authenticate
实体首部
Content-Type : text/html; charset=UTF-8
实体主体内对象的媒体类型
Content-Encoding : gzip
服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩
Content-Length
实体主体部分的大小(单位是字节)。对实体主体进行内容编码传输时,不能再使用Content-Length首部字段
Content-Location : http://www.hackr.jp/index-ja.html
给出与报文主体部分相对应的URI。和首部字段Location不同,Content-Location表示的是报文主体返回资源对应的URI
Allow : GET,HEAD
通知客户端能够支持Request-URI指定资源的所有HTTP方法
当服务器接收到不支持的HTTP方法时,会以状态码405 Method Not Allowed作为响应返回
2XX
【200 OK】:最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据
【204 No Content】 :常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据
206【Partial Content】 :应用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态
3XX
4XX
5XX
报文上的区别
POST /uri HTTP/1.1 \r\n
GET /uri HTTP/1.1 \r\n
GET /index.php?name=qiming.c&age=22 HTTP/1.1 Host: localhost POST /index.php HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded name=qiming.c&age=22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
Cookie 通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态
HTTPS 在 HTTP 与 TCP 层之间加⼊了 SSL/TLS 协议
混合加密
HTTPS 采⽤的是非对称加密和 对称加密 结合的「混合加密」⽅式
采用 混合加密 的原因 :
非对称加密 使⽤两个密钥:公钥和私钥,公钥可以任意分发⽽私钥保密,解决了密钥交换问题但速度慢
对称加密 只使⽤⼀个密钥,密钥必须保密,⽆法做到安全的密钥交换但速度快
摘要算法
数字证书
SSL/TLS 的 握手阶段 涉及 四次 通信
1. Client Hello
首先,由客户端向服务器发起加密通信请求。在这一步,客户端主要向服务器发送一下信息:
客户端支持的 SSL/TLS 协议版本,如 TLS 1.2 版本
客户端生产的随机数(Client Random),后面用于生产 会话秘钥
客户端支持的密码套件列表,如 RSA加密算法
2. ServerHello
服务器收到客户端请求后,向客户端发出响应。 服务端回应的内容有如下:
确认 SSL/TLS 版本协议,如果浏览器不支持,则关闭加密通信
服务器生产的随机数 (Client Random),后面用于生产 会话秘钥
确认的密码套件列表,如 RSA加密算法
服务器的数字证书
3. 客户端回应
客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA公钥,确认服务器的数字证书的真实性
如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:
pre-master key 是整个握手阶段的第三个随机数,这样客户端和服务器同时拥有三个随机数,接着就用双方协商的加密算法,各自生成 本次通信的 会话秘钥
4. 服务器的最后回应
服务器收到客户端的第三个随机数 (pre-master key) 之后,通过协商的加密算法,计算出本次通信的 会话秘钥。然后, 向客户端发出最后的信息:
至此,整个 SSL/TLS 的握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用 会话秘钥 加密内容
Cookie
HTTP Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上
通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能
Cookie 主要用于以下三个方面:
Session
HTTP 协议无状态,意味着浏览器并不知道是哪个用户在和服务端打交道。需要有一个机制来告诉服务端,本次操作用户是否登录,是哪个用户在执行的操作,那这套机制的实现就需要 Cookie 和 Session 的配合
Cookie 和 Session 是如何配合的
第一种方案
第二种方案
通过浏览器解析 URL 并生成 HTTP 消息后,需要委托操作系统将消息发送给 Web 服务器
发送之前需要 查询服务器域名对应的IP地址
DNS服务器专门保存了 Web服务器域名 与 IP 的对应关系
域名的层级关系
域名解析的工作流程
ARP是如何知道对方MAC地址的?
URL元素组成
http: + // + Web 服务器 + / + 目录名 + / + … + 文件名
URL开头表示访问的协议 // 后面的字符串表示服务器的名称 表示数据源(文件)的路径
通过浏览器解析 URL 并生成 HTTP 消息后,需要委托操作系统将消息发送给 Web 服务器
发送之前需要 查询服务器域名对应的IP地址
DNS服务器专门保存了 Web服务器域名 与 IP 的对应关系
域名的层级关系
域名解析的工作流程
通过DNS获取到 IP 后,可以把 HTTP 的传输工作交给操作系统中的 协议栈
应用程序(浏览器) 通过调用 Socket 库,来委托协议栈工作。协议栈的上半部分有两块,分别是收发数据的TCP 和 UDP 协议,会接受应用层的委托执行收发数据的操作
协议栈的下面一般是用 IP 协议控制网络包收发操作,在互联网上传数据时,数据会被切分成一块块的网络包,而将网络包发送给对方的操作就是由 IP 负责的
IP中还包括 ICMP 协议 和 ARP 协议
IP下面的网卡驱动程序负责控制网卡硬件,最下面的网卡则负责完成对网线中的信号执行发送和接受操作
TCP传输数据之前,要先三次握手建立连接
三次握手目的是 保证双方都有发送和接收的能力
如何查看TCP的连接状态
Linux通过 netstat -napt 命令查看
TCP分割数据
如果HTTP请求消息比较长,超过了 MSS 的长度,这时TCP需要把 HTTP 的数据拆解成一块块的数据发送,而不是一次性发送所有数据
数据会被以 MSS 的长度为单位进行拆分,拆分出来的每一块数据都会被进单独的网络包中。也就是在每个被拆分的数据加上TCP头信息,然后交给 IP 模块来发送数据
TCP报文生成
TCP 模块在执⾏连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成网络包发送给通信对象
IP报文头部的格式
在 IP 协议⾥⾯需要有源地址 IP 和 ⽬标地址 IP:
因为 HTTP 是经过 TCP 传输的,所以在 IP 包头的 协议号,要填写为 06 (⼗六进制),表示协议为 TCP
假设客户端有多个网卡,就回有多个IP地址,那IP头部的源地址应该选择哪个IP呢?
需要根据 路由表 规则,来判断哪一个网卡作为源地址 IP
在Linux操作系统,使用 route -n 命令查看当前系统的路由表
假设 Web 服务器的⽬标地址是 192.168.10.200
IP报文生成
⽣成了 IP 头部之后,接下来⽹络包还需要在 IP 头部的前⾯加上 MAC 头部
MAC包头格式
MAC 头部是以太⽹使⽤的头部,它包含了接收⽅(48位)和发送⽅的 MAC 地址(48位)和协议类型(16位)
在 MAC 包头⾥需要 发送⽅ MAC 地址 和 接收⽅⽬标 MAC 地址,⽤于两点之间的传输
一般在 TCP/IP 通信里,MAC包头的 协议类型 只使用
MAC发送方和接收方如何确认
如何获取对方的 MAC 地址呢?
查看 ARP 缓存内容
MAC报文生成
网络包只是存放在内存中的⼀串⼆进制数字信息,没有办法直接发送给对⽅。需要将数字信息转换为电信号,才能在网线上传输,负责执行这⼀操作的是⽹卡,要控制网卡还需要靠⽹卡驱动程序
网卡驱动从 IP 模块获取到包之后,会将其 复制 到网卡内的缓存区中,接着会在其 开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列
交换机的设计是将网络包原样转发到目的地
交换机工作在 MAC 层,也称为 二层网络设备
交换机的包接收操作
交换机的 MAC 地址表主要包含两个信息:
交换机内部有一张 MAC 地址 与网线端口的映射表。当接收到包时,会将相应的端口号和发送MAC地址写入表中,这样就可以根据地址判断出该设备连接在哪个端口上了
交换机根据MAC地址表查找MAC地址,然后将信号发送到相应的端口
当MAC地址表找不到指定的MAC地址会怎样?
以下两个属于广播地址:
MAC地址中的:FF:FF:FF:FF:FF:FF
IP地址中的:255.255.255.255
路由器与交换机的区别
具体的操作,路由器和交换机的区别:
路由器的包接收操作
查询路由表确定输出端口
路由器转发操作
路由器的发送操作
接下来就会进入包的 发送操作
首先,根据 路由表的网关列 判断对方的地址
知道对方的 IP 地址之后,接下来需要通过 ARP 协议 根据 IP 地址查询 MAC 地址,并将查询的结果作为接收方 MAC 地址
客户端查看收到的数据包 HTTP 响应报文后,交给浏览器去渲染页面
客户端要离开了,向服务器发起了 TCP 四次挥⼿,至此双方的连接就断开了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。