网络协议(合集,持续更新....)

原文地址:SuperMonkey的博客

1.基本概念

  • 计算机网络:

    计算机网络是计算机技术和网络技术密切结合的产物,是以能够相互共享资源的方式互联起来的自治计算机系统的集合。

  • 网络互联协议

    为了让计算机网络发展的更好,国际化标准组织ISO在1985年制定了网络互联模型(OSI参考模型)。

    但是ISO制定的OSI参考模型(七层)过于理想化,于是在实际应用中主要使用的协议是TCP/IP协议(四层)。同时为了学习研究,结合OSI参考模型和TCP/IP协议,出现了专为学习研究而生的五层结构。

    image-20221123224530187

2.计算机之间的通信基础

两台计算机之间通信的简易流程

  • 需要将计算机连接起来

  • 需要知道对方的IP地址

  • 需要知道对方的MAC地址(网卡地址)数据都是传送到网卡,被网卡接受。

    • 当接受到数据后,如果网卡发现数据的目标MAC地址是自己,就交给上一层处理。
    • 如果网卡发现数据的MAC地址不是自己,就会将数据丢弃,不会传递给上一层处理。

2.1计算机之间的连接方式

两台计算机之间通信的第一步就是将计算机连接起来。

了解连接方式之前需要知道的一些概念:

  • 全双工通信:接收方和发送发能够同时发送、接受数据。
  • 半双工通信:同一时刻只允许一个方向发送数据,比如对讲机。
  • 连接设备时:相同设备使用交叉线, 不同设备使用直通线(了解)

2.1 连接方式-网线直连

网线直接就是直接把网线的两头接在两台计算机上。

需要使用交叉线,平时带有水晶头的网线就是交叉线。

Snipaste_2022-05-17_23-03-49

2.2 连接方式-同轴电缆

同轴电缆属于半双工通信。

同轴电缆没有智商,线到哪里数据就发送到哪里,如果计算B发送数据, A ,C ,D ,E都能搜到,如果线足够长会一直发送下去,所以需要一个终结电阻。

缺点:

容易冲突,如果A向B发送数据时 , C向D发送数据 就会冲突。

半双工通信 , 不灵活,

如果其中一台主机断了,整个全部瘫痪。

image-20220517231333797

2.3 连接方式-集线器

集线器可以看做是同轴电缆的升级版本,其中一个节点坏了,不会影响到其他节点。

集线器任然会将接受到的消息全部转发到连接到自己的所有设备上。

缺点:

半双工通信,容易冲突,和同轴电缆一样,没有智商。

image-20220517232227892

2.4 连接方式-网桥

如果集线器连接了1000台设备,那么发送一次数据就要转发一千次,长时间占据线路,使用网桥就能做到优化。

网桥只有两个接口,能够通过自学习得知每一个接口哪一侧的MAC地址,只要有一台设备发送了数据,在数据包中会携带着源MAC地址,网桥就会记录这个MAC地址属于哪一边。所以起到了隔绝冲突域的作用。

在下图中, A要发送数据给D ,在第一次通信的时候, A不知到D的MAC地址,所以这个时候就会发送ARP广播协议,当集线器1接受到A发送的数据包时,就会转发给所有连接自己的设备,B 和 C接受到之后就会丢弃,因为目标MAC地址不是他们,当网桥接受到这包数据后,他就会记录下A的MAC地址,然后将数据包发送到集线器2,集线器2将包发送到与自己连接的所有设备,E、F检测到不是自己的MAC,丢弃,D发现是自己的MAC,返回携带着自己MAC地址信息的ARP协议,同样的流程返回, 当A接受到之后,使用IMCP协议发送需要发送的数据到D。

当网桥知道所有主机的MAC地址时,如A发送数据到B的,网桥会检测到发现目标MAC在自己的左边,所以数据包不会再向右边发送

image-20220517234545061

2.5 交换机(局域网的最终方案)

交换机可以理解成集线器加网桥的升级版本。

网桥虽然解决两边互相通信的冲突 , 但是同一边通信时,还是会有冲突 ,此时就有了交换机。

一个接口连接一台机器,每个接口都能够记忆所连接设备的MAC地址,那么就能够知道每一个接口对应的MAC地址,就可以做到精准转发。

作用:相当于接口更多的网桥和集线器的结合体 , 同时还有全双工通信。

image-20220517235206273

2.6 路由器

为什么要使用路由器?

如果全世界所有的电脑都使用交换机连接会怎么样?

如果不使用路由器,全世界的计算机都使用交换机相连会出现:IP地址不够用,因为交换机只能实现同一个网段之间的通信。其次如果不知到mac地址时就需要广播,全球都广播是对资源大量的浪费,所以我们需要使用路由器,让不同网段之间实现通信 。(链路上都是ARP广播协议的话,称之为广播风暴)。

处在同一个网段就是同一个广播域。

为了解决上面的问题,所以决定把计算机网络分段,于是就分成了各个网段,为了能让各个网段之间通信,路由器就诞生了。

路由器作用:

作用:可以在不同网段之间传递数据, 隔绝广播域。

image-20220517235634407

3.MAC地址和IP地址

概述:

在计算机个其他计算机发送消息时 ,需要知道目标ip和MAC地址,发送数据之前计算机都会判断目标ip和自己的ip是不是同一个网段。 这里分为两种情况:

第一种是同一个网段,这个MAC地址是通过ARP协议获取的。比如,两台从来没有通信过的电脑进行通信,我们先ping一下 ,ping其实是使用ICMP协议。在使用ICPMP协议发送数据之前 ,会先使用ARP广播协议,向当前网段中的所有计算机发送目标ip和目标MAC(因为此时不知道目标IP所在电脑的MAC地址,所以目标MAC地址是:FFFF.FFFF.FFFF.FFFF(转换成二进制就是全是1) , 全是1 代表广播),这样这个网段所有的计算机就都收到了源计算机发送来的ARP,然后就会询问到她所需要的MAC地址,这时就会把他所需要的MAC地址带回原主机保存起来,就可以进行ICMP协议通信了。

第二种:不是同一个网段。当发现目标ip与自己不在一个网段之后,计算机会发送一个ARP协议给网关,获取网关的MAC地址,因为要有MAC地址才能发送数据。网关是路由器用来区分网段的,网关的ip地址属于当前连接路由器的网段中的地址,计算机本身也需要配置网关。由路由器根据目标地址的ip找到对应网段的网关,将数据发送出去。

3.1 MAC地址

MAC(Media Access Control Address)地址

每一个网卡都有一个6字节(48bit)的MAC地址

MAC地址全球唯一,固化在网卡的ROM中的。

查看MAC地址

ipconfig /all

image-20220514112949313

可以修改MAC地址蹭网,比如,有些学校的交换机可以设置MAC地址来限制上网的设备的MAC地址,如果你知道一台可以上学校网的MAC地址,你可以把你的MAC改成这个可以上网的MAC地址就可以蹭网了,但是两台相同MAC地址的主机肯定只有一个能上网。

重点:

当MAC地址的48位全部是1的时候,代表广播地址。

ARP:地址解析协议。

作用,通过IP地址获取MAC地址。

RARP:逆地址解析协议。

作用与ARP相反,用于将MAC地址转为IP地址。

使用与ARP相同的报头结构

后来被BOOTP,DHCP所取代

ICMP:互联网控制消息协议。

IPv4中的ICMP被称作ICMPv4,IPv6中的ICMP则被称作ICMPv6

通常用于返回错误信息

✓ 比如TTL值过期,目的不可达

ICMP的错误消息总是包括了源数据并返回给发送者

当不知道对方主机的MAC地址是,可以通过ARP广播获取对方的MAC地址(通过ARP获取的MAC地址属于动态缓存,过两分钟就会清除)。获取成功后,会缓存IP地址,MAC地址的映射信息,俗称:ARP缓存(arp -a 可以查看当前计算机缓存的MAC地址 。 arp -d 删除ARP缓存)。

image-20220515105354361

3.2 IP地址

概述:

互联网上面的每一个主机都有一个ip地址。

最初推出的IPv4,32个bit(4字节),2019年11月25日,全球的IP地址已经用完了。

后面推出了IPv6,128bit(16字节)

详解:

IP地址由两部分组成:网络标识(网络ID) + 主机标识(主机ID)。

有一个ip地址,通过子网掩码就可以获取网络id,主机id。

image-20220518003232010

主机所在的网段 = 子网掩码 & IP地址。

比如

IP地址:192.168.1.10

子网掩码:255.255.255.0

255.255.255.0 (转换成2进制)

&

192.168.1.10 (转换成2进制)

按位与(&)运算规则,1 & 任何数 得 任何数 , 0 & 任何数 得 0

两个二进制按位与的时候,顺序可以互换的。

所以上面这个地址的网络ID是 , 192.168.1

同一网段的计算机,网络id相同。(子网掩码全是1对应的数字就是网络id , 全是0对于的数字就是主机id),所以一个网段能都表示多少台主机,主要是看主机id有多少位,但是要去掉 全是 0 和 全是 1, 全是0代表网段 , 主机ip全是1时代表广播

3.2.1 IP地址的分类

ip地址被分成了五类。

  • A类地址:默认子网掩码是255.0.0.0。
  • B类地址:默认子网掩码是255.255.0.0。
  • C类地址:默认子网掩码是255.255.255.0。
  • D类地址:以1110开头,多播地址。
  • E类地址:以1111开头,保留为今后使用。

注意:只有 A\B\C 类的地址才能分配给主机使用。

主机id全是0,表示该主机所在的网段。

主机id全是1,表示主机所在网段的全部主机(广播),可以尝试ping某个网段的全部主机。

A类地址

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GxYygThd-1671967990300)(http://124.70.40.173:9001/upload/img/image-20220628153429643.png)]

B类地址

image-20220628153556425

C类地址

image-20220628153722803

D、E类地址

image-20220628153924123

子网掩码的CIDR表示方式

  • CIDR:无类别域间路由。

  • 写法 :IP地址/子网掩码1的个数。

    192.1.1.100/24 (这个就表示子网掩码有24个1,也就是子网掩码是:255.255.255.0)

3.2.3 子网划分

子网划分的目的就是减少ip地址的浪费,比如一个网段里面只有500台主机,但是确分配了一个B类网段,如191.100.1.0/16,此时共有 191.100.1.0 ~ 191.100.255.254 台(65534台)主机可以在这个网段,相当浪费。但是如果用一个C类网段,192.168.10.0/24,这个网段能够容纳的主机数量是 192.168.10.1 ~ 192.168.10.254(共253台)台主机,使用C类网段又放不下500台主机了。这时就需要子网划分。

借用主机位作为作为子网位数,划分出多个子网。

等长子网划分:将每一个个网段划分成多个子网,每个子网可用的ip地址数量是一样的

image-20220628164145699

变长子网划分:划分出来的每个子网可用的IP数量不一样。

image-20220628164251142

超网:超网和子网是反过来的,它是将多个连续的网段合并成一个更大的网段。

4.路由

在不同的网段之间转发数据时需要路由器,但是默认情况下路由器只知道和路由器直接连接的网段,非直接连接的网段需要通过静态路由或者动态路由告诉路由器。

静态路由

  • 管理员手动添加路由信息。
  • 适合小规模网路。

动态路由

  • 路由器通过路由协议(如RIP,OSPF)自动获取路由星系。
  • 适合大规模网路。

路由表

  • 需要和非直连的不同网段通信时,需要至少两个路由器,两个路由器连接的ip需要在同一个网段,需要连接哪个网段就配置下一跳的地址和这个网段相同就可以了。

5.ISP和NAT

ISP

ISP(Internet Service Provider)

​ Internet服务提供商,比如电信,移动,网通,铁通等。

​ 我们平时拉的网线和宽带就是通过ISP连接到Internet的。

网络分类

局域网(Local Area Network , LAN)

  • 一般是范围在几百米到十几公里内的计算机所构成的计算机网络

  • 常用于公司、家庭、学校、医院、机关、一幢大楼等

  • 局域网中使用最广泛的网络技术叫:以太网(Ethernet)

  • 在电脑、手机上经常见到的一个英文 WLAN(Wireless LAN),意思是无线局域网

城域网(Metropolitan Area Network,MAN)

  • 一般范围是数十公里到数百公里,可以覆盖一个城市

广域网(Wide Area Network,WAN)

  • 一般范围是几百公里到几千公里,可以覆盖一个国家。通常都需要租用ISP的线路。
公网IP和私网IP

IP地址也分为公网和私网。

公网

  • Internet上的路由器中只有到达公网的路由表,没有到达私网的路由表。
  • 公网IP由因特网信息中心(Inter NIC)同意分配和管理。
  • ISP需要向Inrer INC 申请公网IP

私网

  • 主要用于局域网,私网的保留网段如下:

A类:10.0.0.0/8,1个A类网络。

B类:172.16.0.0/16 ~ 172.31.0.0/16,16个B类网络。

C类:192.168.0.0/24 ~ 192.168.255.0/24,256个C类网段。

NAT

NAT(Network Address Translation)

  • 私网IP在访问Internet的时候需要NAT将私网IP装换成公网IP,转换过程可以由路由器来完成。

作用:

  • 可以节约公网的IP资源。
  • 会隐藏内部的真是IP。

NAT的分类:

  • 静态转换

    • 手动配置NAT映射表。
    • 一对一转换,一个私网IP只能转换成NAT映射表中的公网IP地址。
  • 动态转换:

    • 定义外部地址池,动态随机转换。
    • 一对一转换。
  • PAT

    • 多对一转换,最大程度节约公网IP资源。多个私网IP使用同一个公网IP

    • 采用端口多路复用方式,通过端口号标识不同的数据流。

    • 目前应用最广泛的NAT实现。


6.物理层

在物理层传输的数据被叫做 '流' 。

  1. 作用

物理层定义了接口标准,线缆标准,传输速率,传输方式等。

一条传输介质(网线)上,可以有多条信道。

单工通信:信号只能往一个方向传输,任何时候都不能改变信号的传输方向。比如无线电视,广播,只能接受他们发送来的信号,不能向他们发送。

半双工通信:信号可以双向传输了,但必须是交替进行,同一时刻只能往一个方向传输。对讲机。

全双工通信:信号可以同时双向传输。

做软件开发的,其他就不用了解了。

7.数据链路层

在数据链路层的数据叫做 '帧(frame)'

数据链路层是唯一一个需要在数据头尾都加上数据的层。

  1. 基本概念

    **链路:**从一个节点到相邻节点之间的一段有线或者无线的物理线路,中间没有其他交换节点。如下图中的每一个设备之间的线路都是链路。

    image-20220712224119663

    **数据链路:**在一条链路上传输数据时,需要由对应的通信协议来控制数据的传输。

    • 不同类型的数据链路,通信协议不一样。
    • 广播信道:CSMA/CD协议(比如上图中的 计算机0 —— 集线器 , 交换机0 —— 计算机1)
      • 只要是使用了CSMA/CD协议的都是以太网。
    • 点对点信道:PPP协议(点对点协议,主要是用在两个路由器之间,比如上图中 路由器0 —— 路由器1 的数据链路就是PPP)。

    数据链路层的主要功能:

    • 封装成帧
    • 透明传输
    • 差错检验
  2. 封装成帧

    **帧的结构:**帧是由 帧头,数据部分(也就是网络层传递下来的IP数据包),帧尾三个部分构成。

    image-20220712225323905

    • 最大传输单元MTU:每一种数据链路层协议都规定了所能够传输的帧的数据长度上限。
    • 以太网的MTU为1500个字节。
  3. 透明传输

    透明传输其实就是保证发送和接受的内容一致。

    在透明传输的过程中,使用SOH作为一帧数据的帧开始符,EOT做为帧结束符号,但是其实SOH和EOT本质上都是一段01的编码,帧的数据部分可能会出现和SOH,EOT相同的编码,为了防止接收端将数据部分和SOH,EOT相同的编码当成SOH和EOT,所以使用ESC作为字节填充,接受端在解析时,如果碰到SOH,EOT旁边有ESC,就去掉ESC,将SOH或者EOT当成普通数据。

    image-20220712230631228

    以上是字符填充首位定界符法。

    还有:

    • 字符计数法(在帧头加帧数据长度,如果帧头长度错了,所有数据都错了)。
    • 零比特填充的首尾标志法:使用一个特定的比特模式,0111110来标志帧头和帧尾,如果数据中有连续五个1的编码,就在后面加上一个0,接收方逆着操作。这个方法很容易由硬件来实现,性能优于字符填充法。
    • 违规编码法:使用曼彻斯特编码的方式。
  4. 差错检验

    就是数据链路层首部和帧的数据部分计算出一个冗余码FCS,这个冗余码放到帧尾部,接收方根据这个FCS和接受到的数据计算验证判断数据的正确性。发现有错误就直接丢弃这帧的数据。

    image-20220712232715905

    奇偶校验码:是一种检错码,但是找不到错误在哪里,也不能发现偶数位的错误。

    循环冗余校验码:有纠错功能,但是数据链路层只用了他的检错功能。

    **纠错编码:**海明码,海明码的校验原理有空值得研究。

  5. CSMA/CD协议

    CSMA/CD协议翻译过来的是 载波侦听多路访问/冲突检测 协议。可以联系集线器组网通信时的过程理解这些词。

    使用了CSMA/CD协议的网络就可以称之为以太网,他传输的就是以太网帧。

    • 以太网帧的格式有:Ethernet V2标准、IEEE的802.3标准。
    • 使用最多的是:Ethernet V2标准。
    • 为了能够检测正在发送的帧是否产生了冲突,规定以太网帧至少要64字节。
    • 使用交换机组件的网络,已经支持全双工通信,不需要再使用CSMA/CD,但他传输的帧依旧是以太网帧,所以交换机组建的网也可以叫做以太网。
    • 以太网帧没有帧开始符和帧结束符,以太网帧使用的是曼彻斯特编码,只要信号没有出现跳变,就意味着帧结束了。
    Ethernet V2的帧格式

    image-20220712234120544

    image-20220712234236069

    image-20220712234409972

  6. PPP协议

    Address字段:图中的0xFF 没有作用,因为点到点通信不需要源MAC和目标MAC。

    Control字段:图中的0x03,没有作用。

    Protocol字段:内部用到的协议类型。

    image-20220712234807432

8.网络层

在网络层传输的数据叫 ‘包(packet)’。

IP数据包结构

IP数据包由首部数据两部分组成。

image-20220818230930256

版本(Version):

​ 版本占4位,表示使用的是IPv6还是IPv4。

​ 0b0100:IPv4,

​ 0b0110:IPv6。

首部长度(Header Length):

​ 首部长度占4位,二进制乘以4才是最终长度。

​ 规定首部0b0101: 最小值是20个字节 , 二进制的值是5,乘上4就是20,所以首部最小长度就是20.

​ 首部长度全为1,0b1111,二进制是15,乘上4就是60,所以首部的最大长度就是60个字节。

区分服务(Differentiated Services Field):

​ 区分服务占8个比特位,可以提交网络的服务质量,其实就是包传输的优先级,如果一包数据的这8个比特位设置了值,就会优先传输此包。

总长度(Total Length):

​ 占16位。

​ 16位能够表示的最大值是65536。

​ 由于数据链路层没帧数据不能超过1500字节,所以当IP数据包过大时就要分片

分片就是将数据过大的IP包拆成数据链路层能够接受的小包数据,每个小包数据都是一个完整的IP数据包。

标识(Identification):

​ 占16位。

​ 数据包的ID,每包数据都有一个ID,这个ID就是这个标识,当数据包的数量过大时,需要进行分片处理,会分成多个包,同一个数据包的所有片的标识都是一样的。

​ ID是被一个计数器管理起来的,每发出一个包,ID就加1。

标志(Flags):

​ 标志占3位。

​ 第一位:保留。

​ 第二位:1 代表不允许分片,0代表允许分片。

​ 第三位:1代表不是最后一片,0代表是最后一片(这一位数据非常重要,它关系到我们能够完整的接受到数据)

片偏移(Fragment Offset):

​ 占13位。

​ 片偏移乘以8就是字节偏移数。

​ 所以每一片数据的长度一定是8的倍数。

组装分片数据流程: 分片之后,每一片数据都是一个完成的IP数据包,这些IP数据包在接收到之后顺序是错乱的,这时就需要偏移来排序。字节偏移数为0就表示这是第一包数据,然后根据第一包数据的首部信息就可以算出这包数据的长度,那么0加上第一包数据的长度就是第二包数据的字节偏移数,如果此时发现第二包数据的 标志 的第三位是0,就表示这是最后一片数据了,组装分片完成。如果是1,继续上诉的组装操作。

注意:分片是因为网络层的包太大,而ICMP协议是网络层协议,所以能够直接使用ping一个很大的包让网络层分片。但实际从传输层下来的数据早就已经切分了,切成了一个帧能够容纳的大小,所以凡是从传输层来的数据,网络层都不需要切片。

image-20220819002231470

生存时间(Time To Live):

​ 占8位。

​ 路由器在转发之前都会将TTL减1,一旦发现TTL减为了0,路由器会返回错误报告。

​ 并且每个系统都有默认的TTL,通过ping命令后面的TTL,可以推测出对方的操作系统,中间经过了多少个路由器。

协议(Protocol):

​ 占8位,表明所封装的数据是使用什么协议。

image-20220819113612332

首部检验和(Header Checksum):

​ 用于检查首部是否错误。

ping命令的使用

  • ping /?
    • 查看ping命令的用法
  • ping ip地址 -l 数据包大小
    • 发送指定大小的数据包
  • ping ip地址 -f
    • 不允许网络层分片
  • ping ip地址 -i TTL
    • 设置TTL的值,TTL位置直接填生存时间
  • 通过tracert,pathping命令,可以跟踪数据包经过了那些路由器。
  • ping命令的本质是ICMP协议

9.传输层

在传输层传输的数据叫‘段(segment)’ (数据段)

在传输层有两个协议

  • TCP(Transmission Control Protocol),传输控制协议。
  • UDP(User Datagram Protocol),用户数据报协议。

TCP和UDP的区别

功能特性TCPUDP
连接性面向连接无连接
可靠性可靠传输,不丢包不可靠传输,尽最大努力交付,可能丢包
首部占用空间
传输速率
资源消耗
应用场景浏览器,文件传输,邮件发送音视频通话,直播
应用层协议HTTP,HTTPS,FTP,SMIP,DNSDNS

注意:决定传输层使用TCP或者是UDP是由应用层协议决定的,如表格中,如果应用层协议使用的是HTTP,HTTPS等协议,那么传输层就会使用TCP协议。DNS是可以TCP和UDP通用的。

UDP协议详解

UDP协议的特点就是无连接的,减少建立和释放连接的开销。UDP尽自己最大能力交付,能发多少发多少,但是不保证可靠交付。因为无连接和不保证可靠交付的特点,所以UDP协议不需要维护一些复杂的参数,首部只有8个字节。

UDP的数据格式

image-20220824105213379

协议说明:

16位的UDP长度:

​ 包含了,首部长度 + 数据长度(主要目的是为了占位,并没有实际用处,因为可以通过网路层的头算出这个值)。

​ 不管是TCP还是UDP都可以通过网路层的首部推算出来。网络层的总长度减去网络层首部,再减去8就是传输层UDP数据的长度。

16位的UDP检验和:

​ 检验和的计算内容,伪首部 + 首部 + 数据。

​ 伪首部:仅在计算检验和的时候起作用,并不会传递给网络层。

image-20220824110202170

和端口相关的常用命令

netstat -an: 查看被占用的端口

netstat -anb: 查看被占用的端口,占用端口的应用程序

netstat -aon|findstr “端口”:查看某一个端口的占用情况

telnet 主机 端口 : 参考是否可以访问主机的某个端口

TCP协议详解

TCP协议数据格式

image-20220828093928772

**源端口:**发送端的端口。

**目的端口:**接收方的端口

**数据偏移:**代表TCP协议首部的长度。由图可知,数据偏移占4位,所以取值范围(0x0101 ~ 0x1111)。乘以4就是首部长度,首部长度范围就是 20 ~ 60。TCP协议的首部和网络层的首部长度都是20到60

关于 保留 和 标志 的注意:有些资料说保留只有3位,标志位有9位,这也是正确的,因为标志的前3位是不变的,没有作用。

**保留(Reserved)😗*保留字节占6位。目前全部都是0,没有任何作用。

**标志(Flags):**占6位,这6位数据都是非常有用的。

​ URG(Urgent:当URG为1时,TCP首部里面的紧急指针才有用。紧急指针里面存放的是长度,如果是8,标识TCP数据里面的前8位是紧急数据。

​ ACK(Acknowledgment): 当ACK为1时,确认号才有意义。

​ PSH(PUsh): 用在交互式网络,可以不做了解。

​ RST(Reset): 当RST为1时,说明连接出了严重问题,必须释放连接,然后需要重新建立连接,RST=1就是强制断开连接RST并不需要得到对方的响应,仅仅是一个通知。不会再正常走四次挥手的断开流程。

​ SYN(Synchronization): 当SYN为1 ,ACK=0 时,标识这是一个建立连接的请求。如果对方同意建立连接则回复,SYN = 1 和 ACK = 1。

​ FIN(Finsh): 当FIN = 1 时,表示数据发送完毕,要求释放连接。

序号(Sequence Number):

​ 占4个字节。首先,在传输过程中,每一个字节都会有一个编号。在建立连接后,序号代表,这一次传送给对方TCP数据部分的第一个字节的编号。作用是结合发送的数据长度告诉接收方我发送了多少字节。

简单理解序号(基于建立连接之后的含义):数据在传输层传输的是字节流,字节在内存中都有一个自己的编号,而且让连续的字节编号也是连续的,一长串字节,需要发送到网络层肯定需要分段,分段之后,每一段数据都有自己的TCP首部,首部中的序号就是数据部分的第一个字节的编号。

确认号(Acknowledgment Number):

​ 4个字节,确认号代表,期望对方下一次传送过来的TCP数据部分的第一个字节的编号。作用是告诉发送方我接收到了多少字节。

窗口:

​ 16个bit位,占2个字节。

TCP协议要点

  • 可靠传输
  • 流量控制
  • 拥塞控制
  • 连接管理
    • 建立连接
    • 释放连接

TCP——可靠传输

停止等待ARQ协议

ARQ(Automatic Repeat-reQuest),自动重传请求。

image-20220828103059923

在传输过程中,A发送完M1之后就会有一个等待时间,在这个等待时间之内,如果B正常收到M1并且正常返回确认收到M1,A也收到了确认消息,这就是无差错的情况。如果超时了,A就会选择重新发送M1。

image-20220828104627608

但是可能会出现,第一次发送M1时,B返回的第一次确认延迟了,所以A发送了第二次M1,成功接受,成功确认之后,第一次的确认此时被A接受到了,这时A收下迟到的M1,但是不做任何反应了。

注意:如果有一个包重传了N次还一直失败,会一直传送直到成功吗?这取决于系统的设置,有些系统重传5次还没成功就会发送reset报文(RST)断开TCP连接。

连续ARQ协议 + 滑动窗口协议

停止等待ARQ协议因为有等待时间并且一次发送确认流程只能传送一组数据,效率非常低,所以就出现了 连续ARQ协议 + 滑动窗口协议。

连续ARQ协议

将M1到M4连续发出去,这4个是排好顺序的,如果返回接收到M4就说明前的全部接收成功,接着再发后面的数据,而一次发送多少是由滑动窗口决定的。

滑动窗口协议

接受方的传输层会有一个缓存,这个缓存大小就决定了发送方滑动窗口的大小,滑动窗口的大小是由接收方通过接收确认返回时发送给发送方的。

image-20220828161311672

序号和确认号工作流程

TCP01_序号_确认号

图中细节1:当发送方已经接收到接收方返回的接收确认,就会将缓存中已经确认接收到的数据清除。

图中细节2:当接收方第二次接收到新的数据时,上一次已经确认接收到的数据就会在接收端的缓存中传递给上一层并清除。

图中ACK=601解释:在第二次发送数据时,发现第7个数据段丢失,但是第8个数据段成功发送并接收,这时发送确认返回时就会把将期望的ACK填成601,此时按理应该发送的时 第7 ,8 ,9 ,10组数据,但是实际情况是发现第8组数据已经接收成功了(前提是在接收TCP确认的TCP首部的选项部分发现了SACK选择确认协议),所以就会忽略第8组数据,直发7,9,10组数据。那发送方是如何知道第8组数据已经发送成功的呢?答案就是SACK选择确认协议。SACK是放到TCP首部 选项 里的。

注意:上图中的Sep序号是计算之后的虚拟包序号,原本的Sep是一个非常大的值,这个值需要减去一个固定值,才能得到图中的序号。

滑动窗口大小和数据大小不一样的情况:

​ 接受方告诉发送方滑动窗口大小是400。但是这个时候发送方只有200的数据。正常来说,如果发送方发送了400的数据,接受方会给发送方一个返回确认。但这次只接受到200的数据,接收方等待一段时间,如果还没有数据就直接返回接收到200数据的确认。

SACK选择确认

image-20220828171533732

只发送没有接收到的包,避免发送已发送过的包。SACK可以精确的告诉发送端,那些数据接收到了,那些没有。左边界到右边界之间的数据已经收到的。

为什么要在传输层进行数据段的拆分?

​ 答:在网络层片偏移那里我说过 所有凡是从传输层来的数据,网络层都不需要切片 。原因就是传输层已经将数据段拆分好了。那为什么不在网络层分片呢?因为只有传输层的TCP协议才能保证可靠传输,并且在传输层分片可以提高效率。如果我们在网络层进行切片,中途有一包数据丢失,丢失之后不会重传,对方传输层无法成功组装数据,不会返回ACK确认,不返回ACK确认,发送方的传输层超时之后就会将整一大段数据再次发送,网络层再次分包,如果没有丢失还好,如果有丢失,又需要重传整段数据,效率很低。如果在传输层进行数据分段,中间有一段数据丢了,只需要重传这一段数据就可以了。

TCP——流量控制

概念

如果接收方的缓存区满了,对方还在疯狂的发送数据,接收方就只能吧收到的数据包丢掉,大量的丢包就会浪费网络资源。这是就需要流量控制。

什么是流量控制:

​ 让发送方的发送速率不要太快,让接收方来得及处理。

流量控制原理

通过确认报文中窗口字段来控制发送方的发送速率。

发送方的发送窗口大小不能超过接收方给的窗口大小。

当发送方接收到接收窗口的大小为0时,发送放就会停止发送数据。

TCP02_流量控制

图中描述的流量控制过程中有一种特殊情况,当接收方给发送方发送了窗口为0的报文段,发送方停止发送,过了一段时间,接收方又有了一些存储空间,给发送方发送接收窗口非0的报文段,但是这个报文段丢失。发送方就一直处于停止发送的状态,接收方也接受不到数据,就一直陷入僵持。如何解决这一现象呢?

​ 当发送方收到接收窗口大小为0的报文段时,发送方停止发送并且同时开启一个定时器,隔一段时间就发个测试报文去询问接收发最新的窗口大小。如果接收方返回的窗口大小还是0,则发送方再次刷新启动定时器。

注意:流量控制只存在于发送发和接收方之间,是点对点的,彼此告诉对方窗口的大小,来控制发送速率。

TCP——拥塞控制

概念:

​ 防止过多的数据注入到网路中,避免网路中的路由或者链路过载。

拥塞控制是一个全局性的过程,涉及到所有的主机,路由器,以及降低网络传输性能有关的所有因素是大家共同努力的结果。

负载和链路吞吐量之间的大致关系

image-20220909153709804

(当负载逐渐变大时,链路吞吐量前期也会跟随变大,如果负载达到一个特定值时,此时吞吐量就会开始变小,丢掉多余的包。最终吞吐量会变成0,进入死锁。)

拥塞控制方法

必知名词

  1. MSS(Maximum Segment Size):每个段最大的数据部分大小,在建立连接时确认。确认过程:在建立连接时,接收方和发送给的MSS是不一样的,选择小的那个MSS作为这次连接在传输数据的过程中的数据段最大值。比如建立连接时,协商最小的MSS是1300个字节,那么传输过程种数据段就不能大于1300个字节,如果发送窗口的大小是3600个字节,那么这一次传输一共传输3组数据比较合适。
  2. cwnd(congestion window)拥塞窗口:是发送方根据网络自己调整大小的窗口。
  3. rwnd(receive window)接收窗口:rwnd的大小是由接收方决定的,是接收方告诉发送方最多可以发送多少字节,是一次发送的总数据大小,不是发送一段数据的大小。比如这一次发送4组数据,每一组数据时1200字节,那么rwnd就是4800字节。
  4. swnd(send window)发送窗口: 大小是由发送方决定的,发送窗口真正发送数据的大小。它的取值是 min(cwnd,rwnd)。

三个窗口的关系:

​ 在发送数据时,如果接收方最多可以接收3000字节的数据,那么rwnd就是3000,当发送方知道rwnd的值时,发送方会根据情况判断:

​ 第一种情况:网络状况良好。此时发送方得知cwnd的大小是6000字节,但是接收方只能接收3000字节,发送方就会将swnd的大小的最大值设置成3000字节,然后根据MSS和swnd的值将数据拆成个数合理的数据段发送给接收方。

​ 第二种情况:网络状况不好。此时发送放得知cwnd的大小是2000字节,即使接收方可以接收3000字节,发送方也只会把swnd的大小最大值设置成2000字节,然后根据MSS和swnd的值将数据拆成个数合理的数据段发送给接收方。

无论什么情况,swnd的最大值只能是cwnd和rwnd的最小值。

拥塞控制的方法

  1. 慢开始

    慢开始算法的思路:当主机开始发送数据时,如果立即把大量数据字节注入到网络中,那么就有可能引起网络拥塞,因为现在并不清楚网络的负荷情况。经验证明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值。通常在刚刚开始发送报文段时,先把拥塞窗口cwnd设置为一个最大报文段MSS数值。而在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值,用这样的方法逐步增大发送方的拥塞窗口cwnd,可以使分组注入到网络的速率更加合理。

    1. image-20220909170840278

      由上图可知,MSS的值是100,rwnd的值是3000,不考虑cwnd的情况下,传输过程应该是每包数据段的大小是100,一次能够发30包数据才对。但是图中是慢开始,将拥塞窗口设置成和MSS一样的值,这就意味着一次之只能发一包数据,确认收到之后可以发2包,然后发4包…。所以慢开始就是cwnd的初始值设置的非常小,然后随着数据包被接收方确认(收到一个ACK),cwnd就成倍增长(指数级)。

  2. 拥塞避免

    image-20220909171559453

    分析上图就可以知道拥塞避免是建立在慢开始的基础上的。拥塞避免就是设置一个慢开始的阈值,当cwnd达到阈值之后就开始降低增长速率(从指数级别降低到线性级别,这就是 加法增大),让cwnd增长的缓慢一点,以防止网络过早出现拥塞。当网络出现拥塞的时候(如果出现丢包就代表网络以及拥塞了),立刻将慢开始的cwnd阈值降低为网络拥塞时的一半,同时重新开始慢开始算法,就是将慢开始的cwnd值回复成初始值,然后重复步骤。

  3. 快重传

    image-20220909172718284

    所谓快重传就是字面意思,立刻将丢失的包重新传送,而不等计时器到期,直接就重传。那么它怎么判断那些包是需要快速传送的呢?如图,M3丢失了,返回收到的确认就只有M2,如果收到三个连续的对M2的重复确认就直接重传M3,不会有任何等待时间。

  4. 快恢复

    image-20220909180019175

    当发送方连续收到三个重复确认时,说明有数据包丢失,这就意味着网络出现了拥塞,就执行"乘法减小"算法,把ssthresh就按少为拥塞峰值的一半。就是本来时重新开始慢开始,要将拥塞窗口设置成初始值,但是如果能够重复的收到3个确认,说明网络拥塞的不是太严重,没有必要将拥塞窗口设置成初始,只需要将拥塞窗口的值设置成新的阈值(拥塞峰值的一半),然后开始执行拥塞避免(“加法增大”)。这就是所谓的快恢复。

TCP——连接管理

建立连接——序号和确认号

建立连接的流程。在HTTP请求之前,需要建立TCP连接,建立连接有三次握手。

第一次握手:

​ SYN = 1 , ACK = 0 ,代表客户端去跟服务器请求建立连接,建立连接时数据部分是没有长度的。

第二次握手:

​ SYN = 1 , ACK = 1 , 代表服务器同意建立连接,返回连接确认。

第三次握手:

​ SYN = 0 , ACK = 1 , 客户端指向服务端。

经历了上面的三次握手,连接就建立成功了,这时候就需要客户端向服务器发送HTTP请求。

然后就是连续ARQ协议传输数据

image-20220912194245670

确认号序号在建立连接时的状态

在上述的TCP要点中以及大致的介绍过确认号和序号的工作流程。这里将详细说明。

首先,确认号在抓包软件中是ACK表示确认号,是4个字节的数,同时还有一个标志为的ACK,这个ACK只有一个字节,只是是0或1,如果为1,确认号才有意义。

我们先来看一发送数据时的图(这是一张理想的图,发送一个包,就返回一个确认,同时序号和确认号都是相对值,不是真实值。):

TCP04_序号确认号01_相对

由上图可知:

​ 第一次发送数据时,sep = 1 , 数据长度为 1460

​ 第一次返回确认,ACK = 1461 ,收到1460个数据

​ 第二次发送数据时,sep = 1461 , 数据长度为 1460

​ 第二次返回确认,ACK = 2921。加上已接收的共收到 2920 个数据

​ 第三次发送数据时: sep = 2921 , 数据长度为 1460

​ 第三次返回确认:ACK = 4381.加上已接收的共收到 4380 个数据

由图可知,已经收到的所有数据 + 1 ,就是ACK。

上述所使用的序号和确认号都是相对值,真实的情况中,不会使用相对值,为什么真实情况不用相对值呢?因为相对值的序号和确认号都太简单了,如果被攻击之后,很容易就模拟出后面需要发送的包的序号和长度,因此序号和确认号的真实值是一个非常大的值。

在第一次握手的时候,客户端给服务端了一个序号初始值,这个序号初始值是随机产生的一个很大的数。

在第二次握手的时候,服务端也会给客户端一个序号初始值。

客户端和服务端彼此都可以作为发送方和接收方,在发送数据时,谁发送的数据就用谁的初始值

分析下面的图,结合建立连接时的图看。紫色是客户端,蓝色是服务端。

image-20220912202154258

在第一次握手时:客户端向服务端发送建立连接的请求。标志位 SYN = 1 , ACK = 0 (说明此时确认号没有作用,所以确认号为0),数据部分是0,所以序号也是0,因为这是我是建立连接的请求,不需要发送任何数据。

在第二次握手时,服务端已经接收到了客户端建立连接的请求,服务端需要对这个建立连接的请求做出回应。标志位 SYN = 1 , ACK = 1(说明确认号有意义)。此时数据长度还是0,发送的数据只有一个tcp的头,所以相对的序号还是0。然后服务器希望客户端下一次发送的数据从第1个字节开始,所以确认号ack变成1。

在第三次握手时,客户端收到确认,需要给服务端发送第三次握手请求。这次客户端发送的数据部分还是0,按理说序号应该是0才对,但是这里比较特殊,为了响应第2次握手,所以这里的序号要变成第二次握手的确认号1。至于ack为1的原因和第二次握手一样,第二次握手接收到0个字节,那么这次它就需要下一次服务端能够发送0字节的下一个字节开始的数据,所以ack = 1。

紧接着客户端向服务器发送http请求,这一次请求的确认号和序号和第三次握手是一样的,因为这一次请求都是对第二次握手的回应。但这一次和第三次握手相比,它发送了k字节的数据给服务端

image-20220912202217425

第5个步骤:这个步骤是响应第4个http请求的步骤,http请求发送了k字节的数据,所以服务端希望客户端下次发送k字节开始的下一个字节的数据,所以 ack = k + 1 , 表示前k个字节我已经接收到了。 http请求中ack = 1,说明客户端希望服务端发送序号为1的包,所以这一步骤的seq = 1。len = b1 , 表示服务端已经把序号为1,长度为b1的数据段发送了。

第6个步骤:因为是连续ARQ协议,所以这次还是服务端对客户端http请求的响应,所以ack = k + 1 ,因为第5个步骤以及发送了b1字节的数据,这次就需要发送b1字节后面的数据,所以seq = b1 + 1 ,len = b2。

第7个步骤:同样是对http请求的响应,所以ack = k + 1 , 应为上两个步骤已经发送了b1 + b2 个字节的数据,所以这次需要发送b1 + b2后一个字节的数据,所以seq = b1 + b2 + 1 , len = b3.

第8个步骤同上。

image-20220918123725204

第9个步骤,是连续收到服务器4个TCP数据段之后,客户端做出的响应。按照连续ARQ协议可知,这一次响应需要响应最后接收到的数据段,所以响应第8个步骤,因为第8个步骤的总共发送了,b1 + b2 + b3 + b4个字节,此时客户端需要告诉服务器我已经接收到了 b1 + b2 + b3 + b4个字节的数据,并且希望服务端下次发送已接受到字节的下一个字节为序号的数据 ,所以 ack = b1 + b2 + b3 + b4 +1。在第8个步骤中,因为ack = k + 1 , 所以客户端需要发送k+1序号的数据给服务器, seq = k + 1 。但是这里是一个确认接收的步骤,没有发送任何字节给服务端,len = 0 。所以第10个步骤的ack = k + 1。这就造成了在抓包的时候,出现很多ack值相同的情况。

上面的关于确认号和序号的解析,都是在相对序号和确认号的情况。如果需要分析原生情况,只需要加上原生序号的初始值即可。

序号和确认号变化过程:

image-20220920160943610

建立连接——3次握手

三次握手时客户端和服务器的状态变化:

image-20220920161400852

由图可知:

​ 在没有发送第一次握手之前,客户端处于关闭状态,服务器处于监听状态,服务器一直在监听某个端口,等待客户端连接。
​ 第一次握手,SYN = 1 , ACK = 1 ,seq = x (x时客户端序号初始值) ,这时客户端的SYN = 1 已经发送,所以客户端进入同步已发送状态。服务器接收到客户端第一次握手请求时,知道SYN同步字段为1,然后对第一次握手做出响应,向客户端发送第二次握手,接着进入同步已接收状态。当客户端接收到SYN =1 ,ACK = 1的连接请求确认,然后发送SYN = 1 ,ACK = 1 的第三次握手之后,客户端进入连接已建立状态,服务器也是,在接收到第三次握手后,进入连接已建立状态。然后服务端和客户端开始数据传输。

前两次握手的特点

1.SYN都时1,之后的SYN都是0。

2.数据部分的长度都是0。

3.TCP的头部一般情况下都是32字节,多出的12字节放到选项里,是一些确认信息。

4.客户端和服务端会通过前两次握手交换确认一些信息。例如:

​ MSS:每个段最大的数据部分大小,客户端和服务器都会提供一个,选择小的那个。

​ SACK:是否选择确认。

​ Window scale(窗口缩放系数):只有两个字节,用两个字节来表示肯定窗口大小肯定是不够的,所以这里的窗口换成10进制之后需要乘128或者256才是实际的窗口大小。

为什么握手需要三次,两次不可以吗?

不可以。最主要的目的是为了防止server一直等待,浪费资源。

为什么只有两次握手的时候Server会一直等待?

image-20220920172514216

假设client发出的第一个连接请求报文段,因为网络延迟,在连接释放以后的某个时间才到达server

本来这是一个早已失效的连接请求,但server收到此失效的请求后,误认为是client再次发出的一个新的连接请求

于是server就向client发出确认报文段,同意建立连接

如果不采用“3次握手”,那么只要server发出确认,新的连接就建立了

由于现在client并没有真正想连接服务器的意愿,因此不会理睬server的确认,也不会向server发送数据

但server却以为新的连接已经建立,并一直等待client发来数据,这样,server的很多资源就白白浪费掉了

◼ 采用“三次握手”的办法可以防止上述现象发生

例如上述情况,client没有向server的确认发出确认,server由于收不到确认,就知道client并没有要求建立连接。

如果第三次握手失败怎么办?服务器进入同步已接受状态,并重发,重发超过次数阈值之后,发送RST强制关闭这次连接。

释放连接——4次挥手

image-20221007231508646

4次挥手的过程解读:

​ 第一次挥手:当客户端发送自己没有东西再发送给服务端时,客户端发送连接释放请求,FIN=1,ACK=1,告诉发送方我没有东西在发送给你了。连接释放请求发送完成之后,客户端就进入FIN-WAIT-1(终止等待状态) 。等待服务器响应第一次挥手的确认。

​ 第二次挥手:服务端收到客户端释放连接的请求,发送返回确认。这时就会进入CLSOSE-WAIT(关闭等待状态) , 在这个状态下,服务端就会考虑自己是否还有数据要发送给对方。如果没有,就会发送FIN报文(第三次挥手)给对方。此时客户端接收到服务端返回的ACK确认就会进入FIN-WAIT-2(终止等待状态),等待服务端发送的FIN报文(第三次挥手)。

​ 第三次挥手:服务端经过考虑之后,确认自己没有东西再发送给客户端,就会发送FIN=1的报文,然后进入LAST-ACK状态。这个状态是被动关闭一方在发送FIN之后,最后等待对方的ACK报文。

​ 第四次挥手:当接受到被动关闭的一方发送的FIN之后,发送ACK确认。发送之后,进入时间等待,等待一段时候时间之后,彻底关闭。被动关闭的一方接收到ACK确认,直接关闭。

还有一种比较罕见的状态:CLOSING。:表示你发送FIN报文后,并没有接收到对方的ACK报文,反而是接收到了对方的FIN报文。这时因为双方想同时关闭造成的特殊状态。

细节:

1.TCP/IP的协议中,允许任何一方先发起断开请求。上图是客户端主动要求断开的。

2.主动关闭的一方发送了第四次挥手的ACK报文后,有一个 TIME-WAIT(时间等待)。等待一段时间之后才真的关闭连接。为的是确认服务器端是否收到客户端发出的 ACK 确认报文,当客户端发出最后的 ACK 确认报文时,并不能确定服务器端能够收到该段报文。并且等待时间可以防止新建立起来的连接,错误接收到FIN,从而断开连接。

所以客户端在发送完 ACK 确认报文之后,会设置一个时长为 2MSL 的计时器。

MSL 指的是 Maximum Segment Lifetime:一段 TCP 报文在传输过程中的最大生命周期。

2MSL 即是服务器端发出为 FIN 报文和客户端发出的 ACK 确认报文所能保持有效的最大时长。

服务器端在 1MSL 内没有收到客户端发出的 ACK 确认报文,就会再次向客户端发出 FIN 报文:

  • 如果客户端在 2MSL 内,再次收到了来自服务器端的 FIN 报文,说明服务器端由于各种原因没有接收到客户端发出的 ACK 确认报文。

客户端再次向服务器端发出 ACK 确认报文,计时器重置,重新开始 2MSL 的计时。

  • 否则客户端在 2MSL 内没有再次收到来自服务器端的 FIN 报文,说明服务器端正常接收了 ACK 确认报文,客户端可以进入 CLOSED 阶段,完成“四次挥手”。

为什么释放连接需要4次挥手?

TCP是全双工模式,主机1和主机2可以同时互相发送数据。

第1次挥手:当主机1发出FIN报文段时

​ 表示主机1告诉主机2,主机1已经没有数据要发送了,但是,此时主机1还是可以接受来自主机2的数据

第2次挥手:当主机2返回ACK报文段时

表示主机2已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的。如果这时就彻底断开连接,主机2就没有办法将剩余数据发送给主机1了。

第3次挥手:当主机2也发送了FIN报文段时

​ 表示主机2告诉主机1,主机2已经没有数据要发送了

第4次挥手:当主机1返回ACK报文段时

​ 表示主机1已经知道主机2没有数据发送了。随后正式断开

使用Socket编程抓包三次握手,四次挥手。在抓包过程中,有可能只看到三次挥手,其实是第二次和第三次挥手合并了,当被动关闭的一方收到第一次挥手的FIN时,代表主动的一方没有数据要发给被动的一方了,如果被动发送的一方也没有需要发送的数据了,就会将第2次,和第3次合并。同时告诉主动方两件事。

image-20221008002016283

长连接:即使发完需要的数据,还一直保持连接状态就是长连接。经常需要进行频繁交互的就是使用长连接。

短连接:发送完需要的数据,就断开的连接就是短连接。

10.应用层

应用层的数据叫做 报文

应用层常见的协议

超文本传输:HTTP,HTTPS

文本传输:FTP

电子邮件:SMTP,POP3,IMAP

动态主机配置:DHCP

域名系统:DNS

域名(Domain Name)

由于IP地址不方便记忆,并且不能表达组织的名称和性质,所以设计出来域名。

但是实际上,为了能够准确的访问到主机,最终还是要在知道目标主机的IP地址。

域名申请注册:https://wanwang.aliyun.com/

为什么不直接用域名呢?应为IP地址固定是4个字节,域名随随便便都至少10几个字节,这无疑会增加路由器的负担,浪费流量。

DNS(Domain Name System

DNS协议能偶帮助我们把域名转换成IP地址,DNS可以基于UDP和TCP。,服务占用端口53

image-20221015231041990

在我们通过域名访问服务器时,客户端会先访问最近的一台DNS服务器,也就是客户端自己配置的DNS服务器,这个服务器里面缓存了域名对应的IP地址信息。如果没有缓存就会访问根域名服务器,比如我们现在访问的时baidu.com 其实在com后面有一个 . , 这个 . 就是根域名服务器,然后访问下一级的顶级域名服务器,就是com,然后访问下一级二级域名服务器,会在里面找到baidu,这时就能找到对应的IP地址了,然后返回客户端,客户端将域名对应的ip地址缓存在本地名称服务器中,然后根据ip地址访问百度的服务器。

常用的DNS命令:

ipconfig /displaydns:查看DNS缓存记录

ipconfig /flushdns:清空DNS缓存记录

ping 域名

nslookup 域名

DHCP

IP地址的分类

IP地址按照分配方式可以分成:静态IP地址,动态IP地址。

静态IP

手动设置。适合不怎么挪动的主机,服务器等。

动态IP

从DHCP服务器自动获取IP地址。适合移动设备,无线设备等。

DHCP(Dynamic Host Configuration Protocol)

动态主机配置协议。

DHCP服务器会从IP地址池中,挑选出一个IP地址 出租 个客户端一段时间,时间到期就会收回。

平时家里上网,路由器就可以充当DHCP服务器。

DHCP分配IP地址的4个阶段

  • DISCOVER:发现服务器

    发广播包(源IP是0.0.0.0(因为这时候我还没有IP地址),目标IP是255.255.255.255,目标MAC是FF:FF:FF:FF:FF:FF)

  • OFFER:提供租约

    服务器返回可以租用的IP地址,以及租用期限、子网掩码、网关、DNS等信息

    注意:这里可能会有多个服务器提供租约

  • REQUEST:选择IP地址

    客户端选择一个OFFER,发送广播包进行回应

  • ACKNOWLEDGE:确认

    被选中的服务器发送ACK数据包给客户端

    至此,IP地址分配完成。

DCHP细节

  • DHCP服务器可以跨网段分配IP地址么?(DHCP服务器、客户端不在同一个网段)

    可以借助DHCP中继代理(DHCP Relay Agent)实现跨网段分配IP地址

  • 自动续约

    客户端会在租期不足的时候,自动向DHCP服务器发送REQUEST信息申请续约

  • 常用命令

    ipconfig /all:可以看到DHCP相关的详细信息,比如租约过期时间、DHCP服务器地址等

    ipconfig /release:释放租约

    ipconfig /renew:重新申请IP地址、申请续约(延长租期)

HTTP协议详解

概述

HTTP(Hyper Text Transfer Protocol),超文本传输协议。是互联网应用最广泛的协议之一。

设计HTTP最初的目的是为了发送和接收HTML页面,由URI来标识具体的资源位置。后面HTTP协议就不只是用来传输HTML页面了。

URI和URL的区别,能在全网定位一个资源的URI就是要给URL。

比如:https://liuyangjun.blog.csdn.net/?type=blog这就是一段URL,它能够在全网定位到这个资源。 /login/loginIndex.html 这就是一段URI。

版本变迁:

1991年,HTTP/0.9:

  • 支持GET请求方式获取文本数据(比如HTML),且不支持请求头,响应头,无法向服务器传递太多信息。

1996年,HTTP/1.0:

  • 支持POST、HEAD等请求方法,支持请求头、响应头等,支持更多种数据类型(不再局限于文本数据)浏览器的每次请求都需要与服务器建立一个TCP连接,请求处理完成后立即断开TCP连接。比如当前当前HTML在被浏览器解析是,发现由一个图片资源,就是再次建立TCP连接,然后关闭TCP连接。

1997年,HTTP/1.1

  • 支持PUT,DELETE请求,采用持久连接,多个HTTP请求,可以共用一个TCP连接。
  • 这版协议使用最广泛。

2015,HTTP/2.0

2018,HTTP/3.0

HTTP标准

由万维网协会(W3C)、互联网工程任务组(IETF)协调制定,最终发布了一系列的RFC。

标准查看:

https://www.rfc-editor.org/rfc/rfc2068 (后面的数字换成想查看的PRF标准编号就可以跳转到对应的标准地址)

HTTP报文格式

image-20221021145904505

HTTP的格式要求非常严格,回车换行的使用都是有明确要求的。漏掉一个回车或者换行,服务器就不认。

通常定义HTTP协议最标准的语言就是ABNF,ABNF对于HTTP协议的描述是最准确的。ABNF核心规则在HTTP.pdf里(记得看一看)

请求方法

在RFC 7231中描述了8种请求方法。

GET,POST,HEAD,PUT,DELETE,CONNET,OPTIONS,TRACE

在RFC 5789中又加了一个PATCH方法。

GET:常用于读取操作,请求参数直接拼在URL后面,浏览器对TRL的长度是有限制的。

POST:常用于添加,修改,删除操作,请求参数可以放到请求体中(大小没有限制)

HEAD:该请求能够得到于GET相同的响应,但是没有响应体。场景:在下载一个文件前,先获取大小,再决定是否需要下载,以此可以节约宽带。

OPTIONS:用于获取目的资源所支持的通信选项,比如服务器支持的请求方法。

PUT:用于对已存在的资源进行整体覆盖

PATCH:用于对资源进行部分修改(资源不存在,会创建新的资源)

DELETE:用于删除指定的资源

TRACE:请求服务器回显其收到的请求信息,主要用于HTTP请求的测试或诊断

CONNECT:可以开启一个客户端与所请求资源之间的双向沟通的通道,它可以用来创建隧道(tunnel) 可以用来访问采用了 SSL (HTTPS) 协议的站点

头部字段

按照标准的流程头部字段可以分成四种,请求头字段,响应头字段,实体头字段,通用头字段。但其实按照请求和响应划分,可以只分成两种,请求头字段和响应头字段。

请求头字段:

说明说明示例
User-Agent浏览器的身份标识字符串太长了,打开浏览器按F12查看
Host服务器的域名,端口号Host: localhost:8080
Date发送该消息的日期和时间太长了,打开浏览器按F12查看
Refere表示浏览器访问的前一个页面,正是前一个页面的某个链接将浏览器带到当前页面,用于防盗链Refere: https:www.baidu.com
Content-Type请求体的类型 只有Post请求才有太长了,打开浏览器按F12查看
Content-Length请求体的长度(字节为单位)只有Post请求才有Content-Length: 348
Accept能够接收响应内容的类型(Content-Types)Accept: text\plain
Accept-Charset能够接收的字符文件F12,看浏览器,但这里有个 q = 值。q代表权重值。如果不指定权重值,默认最大1.0
Accept-Encoding能够接受的编码方式列表Accept-Encoding: gzip, deflate, br
Accept-Language能够接受的响应内容的自然语言列表Accept-Language: en-US
Range仅请求某个实体的一部分。字节偏移以0开始。对多线程断点续传有用Range:bytes=500-999
Origin发起一个针对跨越资源共享的请求Origin:https://www.baidu.com
Cookie之前由服务器通过Set-Cookie发送的CookieCookie:$Version=1; Skin=new;
Connection该浏览器想要优先使用的链接类型Connection: keep-alive
Cache-Control用来指定在这次的请求/响应链中的所有缓存机制都必须遵守的指令Cache-Control:no-cache

响应头字段:

说明说明示例
Date发送该消息的日期和时间太长了,打开浏览器按F12查看
Last-Modified所请求的对象最后修改日期F12
Server服务器的名字Server: Apache/2.3.1(Unix)
Expires指定一个时间,超过该时间则认为此响应已经过期Expires: Fri, 21 Oct 2022 10:52:49 GMT
Content-Type响应体类型Content-Type: text/html;charset=UTF-8
Content-Encoding响应内容使用的编码类型Content-Encoding:gzip
Content-Length响应体长度(字节为单位)Content-Length: 285
Content-Disposition可以让客户端下载文件并建议文件名。比如返回的是一段文本,但是想要让文本变成文件就设置它Content-Disposition: attachment; filename=“superMonkey.txt”
Accept-Ranges服务器支持哪些种类的部分内容范围
Content-Range这条部分消息是属于完整消息的那部分Content-Range: bytes 21010-47021/47022
Access-Control-Allow-Origin指定哪些网站可参与到跨来源资源共享过程中Access-Control-Allow-Origin
Location用来进行重定向,或者创建某个新资源使用Location: http:www.w3.org
Connection针对该链接所预期的选项Connection: close
Set-Cookie返回一个Cookie让客户端去保存Set-Cookie:UserID=JohnDoe; Max-Age=3600; Version=1
Cache-Control向从服务器直到客户端在内的所有缓存机制告知,他们是否可以缓存这个对象。单位为秒Cache-Control: max-age=3600

跨域(CORS)

跨域指的是:浏览器不能执行其他网站的脚本,从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。跨域是由浏览器的同源策略造成的,是浏览器施加的安全限制。a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的。

同源:协议,域名(IP),端口三者都相同才是同源。

同源策略规定了ajax只能发送同源的url,如果ajax请求非同源就需要设置跨域。

跨域策略:前后端分离之后,ajax请求肯定会被同源策略限制,此时就需要设置跨域。

想要允许跨域,请求头中都有一个 origin信息,origin后面带着的值就是源头的协议,ip,端口的url , 样例参考请求头的 origin

服务端给回的响应头中也就带着:Access-Control-Allow-Origin信息,值就是Origin中的源头地址,服务器通过这个设置允许谁可以跨域。

场景:前后端分离项目中,前面项目部署在A服务器上,后台项目部署在B服务器上。当用户先访问A时,此时A会把html返回给客户端浏览器展示,但是有些动态数据是需要通过Ajax访问B才能得到的。此时同源策略就起作用了,因为A和B的IP肯定不一样,浏览器就会拒绝展示B返回的数据。解决方法,在需要跨域时,在请求头中设置 origin信息,然后在B接收到请求时,设置响应头的Access-Control-Allow-Origin信息为请求头中Origin的值,这个值就是允许跨域的源。这样就告诉了浏览器,我这个资源是允许我设置的这些源访问。浏览器收到后就会将放回的Json交给页面。

在没有设置跨域的时候,服务器的json其实已经给浏览器了,但是浏览器发现没有设置跨域,就不会把json交给页面。

 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     //设置COPS(允许别人能够跨域访问)
     resp.setHeader("Access-Control-Allow-Origin" , "http://localhost:9896");
 }

Cookie和Session

HTTP请求是无状态请求,对于交互场景没有记忆能力。需要使用Cookie和Session让服务器具有记忆能力。

Cookie:在客户端(浏览器)存储数据,是存储到浏览器所在计算机的硬盘里。在Cookie中有一个domain存储IP和端口,path存储路径。 如果请求时,发现ip,端口,路径都和Cookie中的一样,请求头就会自动带上Cookie。如果没有给Cookie设置有效时间,浏览器关闭,Cookie就销毁

Set-Cookie:这是响应头的字段,服务器就是通过这个字段告诉客户端需要存储的Cookie,SetCookie带回去的就有SessionID和Path

Session:在服务器存储一些数据,存储到服务器的内存中。每个浏览器在服务器上都有单独的Session对象,Session创建成功之后都有一个SessionID,Cookie中存储的是SessionID。

在请求服务器时,如果请求头中没有Cookie,那么服务器有getSession()时就是重新创建一个Session,然后通过Set-Cookie返回SessionID,要是请求头中有Cookie,那个服务器getSession()就会根据Cookie里面的SessionID获取已经存在的Session对象。

Session在服务器的有效时间时30分钟

状态码

状态码的作用是指示HTTP请求是否已成功完成。

状态码的格式固定就是3个数字。

状态码分类

信息响应:100 ~ 199

成功响应:200 ~ 299

重定向:300 ~ 399

客户端错误:400 ~ 499

服务器错误:500 ~ 599

常见状态码

100 Continue:客户端想给服务器发送请求体,但是不知道服务端愿不愿意接收自己的请求体,所以会先发一个不带请求体的请求,如果服务端解析客户端的url和请求头中的数据发现请求体是自己能够接收的,服务端就会返回100的状态码,告诉客户端,可以继续发送请求体。

200 OK 请求成功

302 Found:请求的资源被暂时的移动到有Location头部指定的URL上。

304 Not Modified: 客户端向服务端发送请求时,如果不是第一次请求,服务端也已经响应过一次这个请求,并且服务器本地也没有任何变动,这时服务器就会直接给回客户端304,客户端拿到304,就知道自己需要使用本地缓存。

400 Bad Request:由于语法无效,服务器无法理解该请求

401 Unauthorized:由于缺乏目标资源要求的身份验证凭证

403 Forbidden:服务器端有能力处理该请求,但是拒绝授权访问

404 Not Found:服务器端无法找到所请求的资源

405 Method Not Allowed:服务器禁止了使用当前HTTP方法的请求

406 Not Acceptable:服务器端无法提供与Accept-Charset以及Accept-Language指定的值相匹配的响应

408 Request Timeout:服务器想要将没有在使用的连接关闭。一些服务器会在空闲连接上发送此信息,即便是在客户端没有发送任何请求的情况下

500 Internal Server Error:所请求的服务器遇到意外的情况并阻止其执行请求

501 Not Implemented:请求的方法不被服务器支持,因此无法被处理。服务器必须支持的方法(即不会返回这个状态码的方法)只有 GET 和 HEAD

502 Bad Gateway:作为网关或代理角色的服务器,从上游服务器(如tomcat)中接收到的响应是无效的。

503 Service Unavailable:服务器尚未处于可以接受请求的状态。通常造成这种情况的原因是由于服务器停机维护或者已超载

form提交

form属性:

​ action:请求url

​ method:请求方法,浏览器的表单支持是get和post

​ enctype:POST请求时,请求体的编码方式。application/x-www-form-urlencoded(默认值)。

enctype详解:

作用是控制请求体的编码方式。

使用默认值application/x-www-form-urlencoded就表示,请求体中使用&分割参数,使用=分割健和值,字符用URL编码方式进行编码。

image-20221112122710932

文件上传,文件上传是form表单必须使用 multipart/form-data 的编码方式

使用了multipart/form-data的编码方式,Http请求头中的Content-Type会发生明显变化

image-20221112123117988

代理服务器(Proxy Server)

特点

代理服务器本身不生产内容分,处于中间位置,转发上下游的请求和响应 。

面向下游的客户端,代理服务器是服务器。

面向上游的服务器,代理服务器是客户端。

正向代理

正向代理代理服务器代理的对象是客户端。

image-20221130222156106

作用:

  • 隐藏客户端身份,对于服务器而言,它只知道是代理服务器的访问。
  • 绕过防火墙。本来服务器是不允许客户端A访问的,对As设置了防火墙,但是服务器对代理服务器D并没有设置防火墙,那么A就可以访问代理服务器间接的访问服务器。
  • Internet访问控制,路由器连着互联网,交换机连着很多客户端,我们只需要指定其中一台客户端作为代理服务器,通过路由器设置只允许这个代理服务器能够通过路由器上网,那么在这个局域网内的其他客户端就必须通过这个代理服务器才能上网,这样的话代理服务就能够控制谁能上网,这就是Internet访问控制。
  • 数据过滤:如果代理服务器发现客户端访问的数据是不健康的,就可以过滤掉。

反向代理

反向代理代理的是服务器。

image-20221130222742017

作用:

  • 隐藏服务器的身份。
  • 安全防护:服务器并不直接保留给客户端。
  • 负载均衡:代理服务器可以根据负载均衡算法选择将客户端的请求分到不同的服务器。代理服务器不产生任何运算,只是转发,所以一般情况下一台就够了。

抓包软件原理

Fiddler,Charles等抓包工具其实就是一个代理服务器,它是正向代理,在客户端启动,那么这个客户端所有的请求都会被这个代理服务器捕捉到。

Whireshark除外,它是直接工作在网卡上,捕获网卡的信息。

CDN

CDN(Content Delivery Network或Content Distribution Network):内容分发网络。

作用:利用最靠近美味用户的服务器,更快更可靠的将音乐,图片,视频等资源文件(一般是静态资源)传递给用户。

CDN使用前后对比

image-20221130223701250

没有使用CDN: 在不使用CDN的时候,所有的用户获取资源都需要从服务主机上面获取,照成服务主机负载过重。

使用CDN: 服务主机将所有的资源同步到CDN上,CDN是各个地区的服务器连在一起的网络,主要作用是分发内容。然后用户需要获取资源时,找到距离用户物理位置最近的一台服务器获取,这样就减轻服务器负载,获取速度还快。

CDN运营商在全国,乃至全球各个大枢纽城市都建立了机房。部署了大量拥有高存储高宽带的节点,构建了一个跨运营商,跨地域的专用网络。

image-20221130224856077

image-20221130224911790

使用了CDN之后的请求过程:DNS不知到你对应的ip了,DNS会把你的请求给一个 CDN 的 DNS服务器 , 然后这个CDN的DNS服务器就会给你一个CND负载均衡系统的ip,你再去找这个全局负载均衡的系统,此时这个系统就会找出距离你物理地址最近的一台资源服务器的ip,然后你请求距离你最近的这台服务器,返回你要的资源。如果你访问的资源CDN的边缘节点没有,那么就会CDN父层节点,没有再往上层找,直到找到源站。

网络安全

网络通信中面临的4种安全威胁

image-20221130225041857

**截获:**窃听通信内容

**中断:**中断网络通信

**篡改:**篡改通信内容

**伪造:**伪造通信内容

网络攻击的常见手段

ARP欺骗(网络层): 在两台主机第一次通信之前,肯定需要广播协议获取MAC地址和,目的就是将IP和MAC地址弄成不对等的。

ARP欺骗可以造成的效果

  • 可让攻击者获取局域网上的数据包甚至可篡改数据包
  • 可让网络上特定电脑之间无法正常通信(例如网络执法官这样的软件)
  • 让送至特定IP地址的流量被错误送到攻击者所取代的地方

攻击步骤:

假设主机C是攻击者,主机A、B是被攻击者

  • C只要收到过A、B发送的ARP请求,就会拥有A、B的IP、MAC地址,就可以进行欺骗活动
  • C发送一个ARP响应给B,把响应包里的源IP设为A的IP地址,源MAC设为C的MAC地址
  • B收到ARP响应后,更新它的ARP表,把A的MAC地址(IP_A, MAC_A)改为(IP_A, MAC_C)
  • 当B要发送数据包给A时,它根据ARP表来封装数据包的头部,把目标MAC地址设为MAC_C,而非MAC_A
  • 当交换机收到B发送给A的数据包时,根据此包的目标MAC地址(MAC_C)而把数据包转发给C
  • C收到数据包后,可以把它存起来后再发送给A,达到窃听效果。C也可以篡改数据后才发送数据包给A

DoS攻击(拒绝服务攻击),使目标电脑的网络或系统资源耗尽,使服务暂时中断或停止,导致其正常用户无法访问。

DDoS,找其他僵尸机帮你一起攻击服务器,就变成了分布式

DoS两大类,带宽消耗,就是不断发数据包,占满你的带宽,用户就没办法访问。

SYN洪水攻击,原理就是不断的发送tcp三次握手的第一次握手,然后客户端不给第三次握手,服务器就会一直等待,消耗资源。实现:比如我不断的发送请求,但是我所携带的源地址并不是我自己的源IP,服务器接收到之后就会去返回ACK确认给这个假的源IP,假的源IP这台电脑收到后也懵逼,这不是我发起的,就丢弃,不反回第三次握手,那么服务器就会等待,从而浪费资源。

LAND攻击:发送请求的的源ip和目标ip是一样的,那服务器收到之后,就会给自己返回ACk确认,自己连接自己,直至崩溃。导致循环应答。部分操作系统已经修复了这种漏洞。

DNS劫持,劫持了DNS,域名解析的时候返回的IP是其他IP,然后就访问成了其他IP,这时可能返回一个假冒的网站,获取你的信息。

HTTP劫持,返回给你浏览器执行的JS代码被篡改了,比如访问有些网站时,在右小角多了个莫名其妙的广告弹窗。

HTTP协议存在的安全问题

HTTP协议默认采用的时明文传输,因此有很大的安全隐患。

提高HTTP协议安全的方法,对通信内容进行加密后,在进行传输。

encrypt:加密

decrypt:解密

plaintext:明文

ciphertext:密文

常见的加密方式有

  • 不可逆

    • 单向散列函数:MD5、SHA等 ,现在的全新标准是SHA-3

    • 单向散列函数算出的长度和消息长度无关,无论消息是1bit , 10M , 100G ,单向散列函数都会计算出固定长度的散列值。

    • 散列函数特点:

      • 任意长度的消息,计算出来的散列值都是一样的长度。
      • 计算速度快。
      • 消息不同,散列值不同,即使两份消息只相差一个bit位,结果也千差万别。
      • 单向性,计算之后的散列值无法还原成明文。
    • 名称

      • 单向散列函数也被叫做:消息摘要函数,哈希函数
      • 输出的散列值也被叫做:消息摘要,指纹

      单向散列如何防止被篡改?其实就是将源文件生成散列值保存起来,如果发现后面的文件生成的散列值和源文件的散列值不一样,说明文件被篡改了。

    • 单向散列值应用:

      • 密码加密,加密之后存到数据库,即使攻击者获取到了数据库的密码,也是散列值,无法被解密。
  • 可逆

    • 可逆就是生成的密码是可以解密回来的。加密时通过一个密钥加密,解密时也使用一个密钥解密。

    • 对称加密:加密的密钥和解密用的密钥是同一份。DES、3DES、AES等

      • 对称加密现在主流使用AES
      • 存在问题,密钥配送问题:
        • 在使用对称加密的时候,一定会遇到密钥配送的问题。因为要想肯定要在网络中发送这个密钥,那这个密钥就很有可能被监听者获取,然后在获取你的密文,就可以解密了。
        • 解决方案:
          • 事先共享密钥(私下共享,不在网络中传输)。
          • 密钥分配中心(KDC)来分配密钥。
          • 非对称加密
    • 非对称加密:加密时的密钥和解密时的密钥不是同一份,RSA等

    • 非对称加密是如何解决对称加密种的密钥配送问题的?

      • 加密密钥:一般是公开的,也叫做公钥。所以非对称加密也叫公钥密码。

      • 解密密钥:由消息接收者自己保管,不能公开,也叫做私钥。

      • 公钥和私钥是一对的,不能单独生成。只有同一对公钥和私钥才能解密成功。

        解决流程:由消息接收者,生成一对公钥和私钥,将公钥发送给消息发送者,公钥是公开的,谁都可以获取。然后发送者通过这个公钥对消息进行加密,此时即使公钥和密文被监听也不无法解密。只有消息接收者,收到密文后,使用对应的私钥解密。

        注意:非对称加密,解密的速度比对称加密要慢很多。

  • 其它

    • 混合密码系统

      • 在非对称加密中,虽然解决了密钥会被窃听的问题,但是加密解密速度太慢。如果消息太大,时间就会很长。所以还是使用 对称加密 加密消息。
      • 混合加密:使用会话密钥作为本次通信的临时密钥,用这个会话密钥作为对称加密的密码加密消息。然后再用消息接收者提供的公钥加密这个会话密钥。将密文和被加密的会话密钥一起发送给消息接收者。消息接收者接收到之后,需要使用私钥才能得到正确的会话密钥,才能进一步解开密文,得到明文。即使中间密文和被加密的会话密钥被监听,监听者也无法解开会话密钥。
    • 数字签名

      • 在保证消息能够安全到达接收方后。又有一个问题,如果方送方给接收方发送了一个不好的消息,发送方确狡辩说不是自己发送的。或者有人冒充发送方给接收方发送消息,该怎么证明发送者的身份呢?又如何保证发送的消息没有被篡改?

      • 签名的过程

        • 消息发送者自己生成密钥对,发送者用自己的私钥将发送的消息加密成签名,这个签名和需要发送的消息一起发送给接收方,接收方收到之后,使用发送方提供的公钥解密签名,如果解密不出来,说明这个消息不是发送方发送的,如果解密后签名消息和消息本身不一样,证明这个消息被篡改了。但这样存在一个问题,因为解密密文是使用非对称加密,速度慢,如果消息内容太大,非常不合适,所以发送发会将消息使用单向散列函数进行加密,这个不管多大的消息最后生成的都是一个固定长度的密文。发送方对这个密文进行签名。接收方接收到之后,也是使用同样的单向散列函数对消息加密,用这个加密后的密文和解出来的签名做对比,效果是一样的,而且提高了加密解密的速度。

          注意,签名和非对称加密是反的。签名使用私钥加密,公钥解密,消息发送方生成密钥对。非对称加密使用公钥加密,私钥解密,消息接收发生成密钥对。

    • 证书

      在非对称加密中,公钥是所有人都可以获取的。这是存在一个问题,如果有一个监听者,在消息发送方向消息接收者询问公钥时,攻击者将原本属于接收者的公钥改成攻击者的公钥。那么消息发送者就会使用攻击者的公钥加密明文,然后发送给消息接收者,此时攻击者监听到这个消息,因为是攻击者自己的公钥,所以攻击者可以通过自己的私钥解密出密文。攻击者的公钥是不合法的。如何解决呢?

      使用签名的效果是一致的,因为签名本身也要使用公钥,还是会出现公钥合法性问题。需要使用公钥证书。

      因为公钥必须发给别人,所以公钥会被中间人伪造。为了保证公钥合法性,所以用到了证书。

      证书里面要有个人信息,此人的公钥,因为要证明这个公钥属于此人,还有认证机构(CA)的签名。只有CA能够认定这个公钥属于此人。

      证书使用:

      ​ 消息接收者需要生成密钥对,然后将公钥发送给认证机构,这个发送过程是又自己保证安全的手段的

      ​ 认证机构收到消息发送者的公钥后,会生施加自己的签名并生成证书。

      ​ 认证机构会将使用密钥加密证书,供消息发送者下载,各大CA的公钥,默认内置再来浏览器和操作系统里面。

      查看Windows已经信任的证书

      ① Windows键 + R >>> 输入mmc

      ② 文件 >>> 添加/删除管理单元

      ③ 证书 >>> 添加 >>> 我的用户账户 >>> 完成 >>> 确定

HTTPS

HTTPS(HyperText Transfer Protocol Secure),译为:超文本传输安全协议。

可以理解为,使用 TLS 的HTTP协议,或使用了SSL的HTTP协议,或使用Secure的HTTP协议。HTTPS其实就是对HTTP协议的报文进行加密

HTTPS的默认端口是443,HTTP的默认端口是80。

HTTPS相对HTTP变的非常安全,但是HTTPS使用成本比较高,需要 支付证书费用,加解密计算,以及降低了访问速度。所以有些企业是包含敏感数据才使用HTTPS,其他保持HTTP。

SSL/TLS

HTTPS是在HTTP的基础上使用了 SSL/TLS 来加密报文,对窃听中间人攻击提供合理的防护。

SSL/TLS不仅仅可以用在HTTP协议上,还可以在FTP上使用(FTPS),SMTP上使用(SMTPS)。

TLS(Transport Layer Security):传输层安全性协议

TLS的前生是SSL(Secure Sockets Layer)“安全套接层”.

image-20221219234321177

SSL和TLS工作在传输层和应用层之间。

OpenSSL是对SSL的一种开源实现,Linux和Mac一般自带OpenSSL

Windows下载OpenSSL: https://slproweb.com/products/Win32OpenSSL.html

OpenSSL的常用命令:

生成私钥:openssl genrsa -out zhanghuan.key

生成公钥:openssl rsa -in zhanghuan.key -pubout -out zhanghuan.pem

可以使用OpenSSL构建一套属于自己的CA,自己给自己颁发证书,称为“自签名证书”

HTTPS的通信过程

分成3大阶段

  1. TCP的三次握手,建立数据传输的通道
  2. TLS的连接,确实如何加密,解密
  3. HTTP请求和响应,传输和响应被TLS加密的数据
image-20221219235354565

TLS 1.2的连接过程

image-20221220002035582

主要步骤是10个。

图中省略了中间产生的一些ACK确认。

步骤详解携带信息

  1. Client Hello
    • TLS的版本号
    • 支持的加密组件(Cipher Suite)列表 (加密组件是指所使用的加密算法及密钥长度等)
    • 一个随机数(Client Random)
  2. Server Hello
    • TLS的版本号
    • 选择的加密组件 (是从接收到的客户端加密组件列表中挑选出来的)
    • 一个随机数(Server Random)
  3. Certificate
    • 服务器的公钥证书(被CA签名过的)
  4. Server Key Exchange
    • 用以实现ECDHE算法的其中一个参数(Server Params)
      • ECDHE是一种密钥交换算法
      • 为了防止伪造,Server Params经过了服务器私钥签名
  5. Server Hello Done
    • 告知客户端:协商部分结束。
    • 目前为止,客户端和服务器之间通过明文共享了 Client Random、Server Random、Server Params
    • 而且,客户端也已经拿到了服务器的公钥证书,接下来,客户端会验证证书的真实有效性
  6. Client Key Exchange
    • 用以实现ECDHE算法的另一个参数(Client Params)
    • 目前为止,客户端和服务器都拥有了ECDHE算法需要的2个参数:Server Params、Client Params
    • 客户端、服务器都可以的操作:
      • 使用ECDHE算法根据Server Params、Client Params计算出一个新的随机密钥串:Pre-master secret
      • 然后结合Client Random、Server Random、Pre-master secret生成一个主密钥
      • 最后利用主密钥衍生出其他密钥:客户端发送用的会话密钥、服务器发送用的会话密钥等
  7. Change Cipher Spec
    • 告知服务器:之后的通信会采用计算出来的会话密钥进行加密
  8. Finished
    • 包含连接至今全部报文的整体校验值(摘要),加密之后发送给服务器
    • 这次握手协商是否成功,要以服务器是否能够正确解密该报文作为判定标准
    1. 9-Change Cipher Spec 10-Finished
      • 到此为止,客户端服务器都验证加密解密没问题,握手正式结束
      • 后面开始传输加密的HTTP请求和响应

HTTP的升级

HTTP/1.1不足:

  • 同一时间,一个连接只能对应一个请求,就是TCP建立的通道可以复用,HTTP需要排队,需要并发需要两个TCP连接。

  • 针对同一个域名,大多浏览器只允许同时最多6个并发连接。就是访问同一个网站,一次性最多可以建立6个TCP连接。

  • 只允许客户端发起请求,一个请求只能对应一个响应。

  • 同一个会话的多次请求,头信息会被重复传输。请求头里,相同的信息被反复请求,响应。

改进

SPDY(speedy的缩写),是基于TCP的应用层协议,它强制要求是SSL/TLS。

2009年11月,Google宣布将SPDY作为提高网络速度的内部项目。

SPDY与HTTP的关系

SPDY只是修改了HTTP请求与响应的传输方式。

只需增加一个SPDY层,现有的所有服务端应用均可以不做任何修改。

SPDY是HTTP/2的前生,2015年9月,Google宣布移除SPDY的支持,拥抱HTTP/2

image-20221225171350710

HTTP/2.0

HTTP/2.0,在2015年5月正式发表,已经成为标准。

全球有越来越多的网站支持了HTTP/2。

HTTP/2在底层传输做了很多的改进和优化,但在语义上和HTTP/1.1兼容。

各种请求方法,GET,POST等都没有变,各种headers也没有改变。

如何升级到HTTP/2?

  • 开发人员不需要修改任何代码。
  • 只需要升级服务器配置,升级浏览器。

HTTP/2的特性

  1. 二进制格式
    • HTTP/1.1采用文本格式传输数据,而HTTP/2采用二进制格式传输数据
    • 二进制格式对于协议的解析和优化扩展带来了更多的优势和可能
  2. 基本概念:
    • 数据流:存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数ID。已建立的连接内可以双向传递的字节流,可以承载一条或者多条信息。所有的通信都在一个TCP的连接上完成,此链接可以承载任意数量的双向数据流。
    • 帧:HTTP/2数据通信的最小单位消息:指HTTP/2中逻辑上的HTTP消息。例如请求和响应,消息由一个或者多个帧组成。每个帧都包含帧头(会标识出当前帧所属的数据流)。来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重新组装。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4XLiBGS3-1671967991082)(null)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bzPRiLxL-1671967992264)(null)]

  1. 多路复用:

    • 客户端和服务器可以将HTTP消息分解为互不依赖的帧,然后交错发送,最后再在另一端把他们重新组装起来。
    • 并行交错的发送多个请求,请求之间互不影响
    • 并行交错的发送多个响应,响应之间互不干扰。
    • 使用一个连接可以并行发送多个请求和响应。
    image-20221225175033613

    一个TCP连接,可以同时处理多次请求和响应,这些请求和响应会被一起分成很多小的帧发送。但是HTTP的响应任然是按照请求的顺序响应的。

  2. 头部压缩:

    • img
    • 客户端发了两次请求,第一次请求有完整的http报文头部,第二次请求的时候只有一个path的字段不一样,但是这次报文头它只需要发送一个path的字段就好了,这样就大大减少了发送的量。这个的实现要求客户端和服务同时维护一个报文头表。上面提到的少了4kb的流量很可能是这个节省下来的。这个的意义还是很大的,因为动态请求有时候可能只需要发送几个字节的数据,但却需要发送一个几百个字节的报文头
    • HTTP/2使用HPACK压缩请求头和响应头。可以极大减少头部开销,进而提高性能
    • 早期版本的HTTP/2和SPDY使用 zlib压缩 ,可以将所传输头数据的大小减小85%~88%
    • 但在2012年夏天,被攻击导致会话劫持后被更换成安全的HPACK。
  3. 服务器推送:

    • 服务器可以对一个客户端的请求发送多个响应。除了对最初请求的响应外,服务器还可以向客户端推送额外资源,而无需客户端额外明确地请求。
    • 但是也必须是有一个客户端请求的情况下才可以,没有办法在没有客户端发送请求时服务器主动响应。

HTTP/2存在的问题

  1. 队头阻塞:
    • 在HTTP/2中,多个请求是跑在一个TCP管道中的。但当出现了丢包时,HTTP/2 的表现反倒不如 HTTP/1 了。因为TCP为了保证可靠传输,有个特别的丢包重传机制,丢失的包必须要等待重新传输确认,HTTP/2出现丢包时,整个 TCP 都要开始等待重传,那么就会阻塞该TCP连接中的所有请求。而对于 HTTP/1.1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。
    • image-20221225182444474
  2. 握手延迟:
    • 在http/2的通信过程中,TCP本身就是就存在RTT(往返延迟),TCP+TLS,TLS也需要建立连接,协商会话密钥,所以往返延迟比单独的TCP还长。
    • image-20221225183051483

HTTP/3

Google觉得HTTP/2仍然不够快,于是就有了HTTP/3

HTTP/3由Google开发,弃用TCP协议,改为使用基于UDP协议的QUIC协议实现

QUIC(Quick UDP Internet Connections),译为:快速UDP网络连接,由Google开发,在2013年实现

于2018年从HTTP-over-QUIC改为HTTP/3。

HTTP/2中存在的两个问题,究其根本其实就是传输层使用了TCP协议导致的。为了解决这些问题,所以需要使用UDP协议来作为传输层的传输协议。为什么非要在TCP和UDP之间选择,各种折腾。Google自己开发一套新的传输协议不行吗?不行,成本太高,因为传输层的协议是定在操作系统里面的,并且全世界的通信设备都只认识TCP和UDP,重新开发传输层协议,就需要把全世界的网络设备,操作系统都换一遍,这显然不可能实现。img

HTTP/3基于UDP,如何保证可靠传输?

由QUIC来保证,在QUIC中,实现了可靠传输。发送方和接收方的QUIC来验证是否丢包,是否需要重传。

连接迁移

TCP基于4要素(源IP、源端口、目标IP、目标端口)

切换网络时至少会有一个要素发生变化,导致连接发生变化

当连接发生变化时,如果还使用原来的TCP连接,则会导致连接失败,就得等原来的连接超时后重新建立连接

所以我们有时候发现切换到一个新网络时,即使新网络状况良好,但内容还是需要加载很久

如果实现得好,当检测到网络变化时立刻建立新的TCP连接,即使这样,建立新的连接还是需要几百毫秒的时间

QUIC的连接不受4要素的影响,当4要素发生变化时,原连接依然维持

QUIC连接不以4要素作为标识,而是使用一组Connection ID(连接ID)来标识一个连接

即使IP或者端口发生变化,只要Connection ID没有变化,那么连接依然可以维持

比如 :

​ 当设备连接到Wi-Fi时,将进行中的下载从蜂窝网络连接转移到更快速的Wi-Fi连接

​ 当Wi-Fi连接不再可用时,将连接转移到蜂窝网络连接

HTTP/3的问题

对计算机性能要求变高

据Google和Facebook称,与基于TLS的HTTP/2相比,它们大规模部署的QUIC需要近2倍的CPU使用量

Linux内核的UDP部分没有得到像TCP那样的优化,因为传统上没有使用UDP进行如此高速的信息传输

TCP和TLS有硬件加速,而这对于UDP很罕见,对于QUIC则基本不存在

随着时间的推移,相信这个问题会逐步得到改善

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值