目录
1.3. PAT(端口地址转换,Port Address Translation)/NAT Overload
2. 加权轮询法(Weighted Round Robin)
1. 网络基础知识
-
OSI七层模型
-
TCP/IP模型
以下是计算机网络中各层的常见协议表格:
OSI 模型层级 | 协议名称 | 说明 |
---|---|---|
物理层 | 无线协议(Wi-Fi、Bluetooth) | 负责设备间的比特流传输。 |
光纤传输协议(SONET、SDH) | 用于光纤通信中的数据传输。 | |
数据链路层 | 以太网(Ethernet) | 常见的局域网(LAN)协议,用于定义数据帧的格式和传输。 |
PPP(Point-to-Point Protocol) | 点对点协议,常用于广域网(WAN)连接。 | |
ARP(Address Resolution Protocol) | 地址解析协议,用于将 IP 地址解析为 MAC 地址。 | |
VLAN(Virtual Local Area Network) | 用于划分虚拟局域网。 | |
网络层 | IP(Internet Protocol, IPv4/IPv6) | 负责数据包在不同网络之间的传输,提供无连接的网络服务。 |
ICMP(Internet Control Message Protocol) | 网络控制报文协议,用于网络设备之间发送控制消息,如 Ping。 | |
OSPF(Open Shortest Path First) | 开放最短路径优先协议,一种路由协议,基于链路状态选择路径。 | |
RIP(Routing Information Protocol) | 路由信息协议,一种基于距离向量的路由协议。 | |
BGP(Border Gateway Protocol) | 边界网关协议,用于互联网自治系统之间的路由。 | |
传输层 | TCP(Transmission Control Protocol) | 传输控制协议,提供可靠的、有序的数据传输。 |
UDP(User Datagram Protocol) | 用户数据报协议,提供无连接、不可靠的数据传输。 | |
SCTP(Stream Control Transmission Protocol) | 流控制传输协议,用于传输多个数据流,适合信令传输。 | |
会话层 | SMB(Server Message Block) | 用于共享文件和打印机。 |
RPC(Remote Procedure Call) | 远程过程调用协议,允许程序在另一台计算机上执行代码。 | |
PPTP(Point-to-Point Tunneling Protocol) | 点对点隧道协议,用于创建虚拟专用网络(VPN)。 | |
表示层 | SSL/TLS(Secure Sockets Layer / Transport Layer Security) | 用于加密网络传输中的数据,保证通信安全性。 |
JPEG、MPEG、GIF | 图片、视频、图形格式传输协议。 | |
应用层 | HTTP(HyperText Transfer Protocol) | 超文本传输协议,用于万维网上的网页传输。 |
HTTPS(HTTP Secure) | 加密的 HTTP 协议,使用 SSL/TLS 进行安全传输。 | |
FTP(File Transfer Protocol) | 文件传输协议,用于文件的上传与下载。 | |
SMTP(Simple Mail Transfer Protocol) | 简单邮件传输协议,用于发送电子邮件。 | |
POP3/IMAP(Post Office Protocol/Internet Message Access Protocol) | 用于接收电子邮件。 | |
DNS(Domain Name System) | 域名系统,用于将域名解析为 IP 地址。 | |
SSH(Secure Shell) | 安全外壳协议,用于远程登录和命令执行。 | |
SNMP(Simple Network Management Protocol) | 简单网络管理协议,用于管理和监控网络设备。 |
-
2. 传输层
-
TCP
序列号:该报⽂段⾸字节的字节流编号。
确认应答号:对发送来的 TCP 报⽂段的响应,值是收到的TCP报⽂段的序号值加1,⽤来解决不丢包的问题。序列号和确认应答号都⽤于实现可靠数据传输。
⾸部⻓度:标识TCP头部有多少字节,最⻓ 60。
窗⼝⼤⼩:接收窗⼝,告诉对⽅本端TCP缓冲区还有多少空间可以接收数据,⽤来做流量控制。
标志字段:
ACK:⽤于指示确认应答号值是否有效,置1表示包含⼀个对已成功接收报⽂段的确认;
RST:⽤于重置⼀个已经混乱的连接,或拒绝⼀个⽆效的数据段或者连接请求;
SYN:⽤于连接建⽴过程,请求建⽴⼀个连接;
FIN:⽤于断开连接,表示发送⽅没有数据要传输了。
检验和:接收⽅使⽤检验和来检查该报⽂段(头部+数据)中是否出现差错(CRC算法)。
-
三次握手
1、第⼀次握⼿:SYN报⽂:
客户端随机初始化序列号 client_isn ,放进TCP⾸部序列号段,然后把SYN置1。把SYN报⽂发送给服务端,表示发起连接,之后客户端处于SYN-SENT状态。
2、第⼆次握⼿:SYN+ACK报⽂:
服务端收到客户端的SYN报⽂之后,会把⾃⼰随机初始化的序号 server_isn 放进TCP⾸部序列号段,「确认应答号」填⼊ client_isn + 1 ,把SYN和ACK标志位置为1。把SYN+ACK报⽂发送给客户端,然后进⼊ SYN-RCVD 状态,表示服务器接受了客户端的请求,并希望建⽴连接。
3、第三次握⼿:ACK报⽂:
客户端收到服务端报⽂后,还要向服务端回应最后⼀个应答报⽂。⾸先该应答报⽂ TCP ⾸部 ACK 标志位置为1 ,其次「确认应答号」字段填⼊ server_isn + 1 ,最后把报⽂发送给服务端,这次报⽂可以携带客户到服务器的数据,之后客户端处于 ESTABLISHED 状态, 表示客户端已经准备好与服务器进⾏数据传输。服务器收到客户端的应答报⽂后,也进⼊ ESTABLISHED 状态。此时,TCP 连接已经建⽴起来,通信双⽅可以开始进⾏数据传输。
为什么是三次
1. 三次握⼿才可以阻⽌重复历史连接的初始化(主因):由于网络原因客户端多次请求链接
2. 三次握⼿才可以同步双⽅的初始序列号
3. 三次握⼿才可以避免资源浪费:3次就够了,4次多余
四次挥手
在挥⼿之前,客户端和服务器都处于 ESTABLISHED 状态
1. 第⼀次挥⼿:假设客户端打算关闭连接,发送⼀个TCP⾸部FIN被置1的 FIN 报⽂给服务端, 此时客户端处于FIN_WAIT1 状态
2. 第⼆次挥⼿:服务端收到以后,向客户端发送ACK应答报⽂,且把客户端的序列号值+1作为ACK报⽂的序列号
值,表明已经收到客户端的报⽂了,此时服务端处于 CLOSE_WAIT 状态
3. 第三次挥⼿:等待服务端处理完数据后,向客户端发送FIN报⽂。此时服务端处于 LAST_ACK 的状态
4. 第四次挥⼿:客户端接收到FIN报⽂后回⼀个ACK应答报⽂,之后客户端处于 TIME_WAIT 状态
5. 服务器收到ACK报⽂后,进⼊ CLOSE 状态,服务器完成连接关闭。
6. 客户端在经过 2MSL ⼀段时间后,⾃动进⼊ CLOSE 状态,客户端也完成连接的关闭。
为什么是四次
服务端通常需要等待完成数据的发送和处理,所以服务端的ACK和FIN⼀般都会分开发送,从⽽
⽐三次握⼿导致多了⼀次。
TIME_WAIT 状态
主动发起关闭连接的⼀⽅,才会有 TIME-WAIT 状态。
需要 TIME-WAIT 状态,主要是两个原因:
1. 防⽌历史连接中的数据,被后⾯相同四元组的连接错误的接收;
如果⽹络出现拥塞或延迟,数据包可能会在⽹络中滞留⼀段时间,甚⾄超过了原始连接关闭的时间。
如果没有TIME_WAIT 状态,客户端直接进⼊到CLOSE状态,这些滞留的数据包可能会被传递给新连接,
导致新连接的数据被旧连接的数据⼲扰。经过 2MSL 这个时间,⾜以让两个⽅向上的数据包都被丢弃,使得
原来连接的数据包在⽹络中都⾃然消失,再出现的数据包⼀定都是新建⽴连接所产⽣的。
2. 保证「被动关闭连接」的⼀⽅能被正确的关闭,即保证最后的 ACK 能让被动关闭⽅接收,从⽽帮助其正常
关闭如果最后的⼀次ACK报⽂丢失(第四次挥⼿),客户端没有 TIME_WAIT 状态,直接进⼊ClOSE,服务端⼀
直在等待ACK状态,⼀直没有等到,就会重发FIN报⽂,⽽客户端已经进⼊到关闭状态,在收到服务端重传的
FIN 报⽂后,就会回 RST 报⽂,服务端收到这个 RST 并将其解释为⼀个错误, 为了防⽌这种情况出现,客户
端必须等待⾜够⻓的时间,确保服务端能够收到 ACK,如果服务端没有收到 ACK,那么就会触发 TCP 重传机
制,服务端会重新发送⼀个FIN,这样⼀去⼀来刚好两个 MSL 的时间。
如果 TIME-WAIT 等待⾜够⻓的情况就会遇到两种情况:
1. 服务端正常收到四次挥⼿的最后⼀个 ACK 报⽂,则服务端正常关闭连接。
2. 服务端没有收到四次挥⼿的最后⼀个 ACK 报⽂时,则会重发 FIN 关闭连接报⽂并等待新的 ACK 报⽂。
为什么 TIME_WAIT == 2MSL
1. MSL是 Maximum Segment Lifetime ,报⽂最⼤⽣存时间,它是任何报⽂在⽹络上存在的最⻓时间,超过这
个时间报⽂将被丢弃。
2. 等待MSL两倍:⽹络中可能存在发送⽅的数据包,当这些发送⽅的数据包被接收⽅处理后⼜会向对⽅发送响
应,所以⼀来⼀回需要等待 2 倍的时间。
3. 1 个 MSL 确保四次挥⼿中主动关闭⽅最后的 ACK 报⽂最终能达到对端;1 个 MSL 确保对端没有收到 ACK 重传的 FIN 报⽂可以到达。
4. 2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK没有传输到服务端,客户端⼜接收到了服务端重发的 FIN 报⽂,那么 2MSL 时间将重新计时。
TCP连接的状态变化
传输控制
重传机制
通过序列号和应答(ack)机制实现
超时重传
设定⼀个计时器,当超过指定的时间后,没有收到对⽅的确认ACK应答报⽂,就会重发该数据。
快速重传
当收到三个相同的ACK报⽂时,会在定时器过期之前,重传丢失的报⽂段。
滑动窗⼝
发送放不用等ack,直接发送对面接受能力的报文。
窗⼝大小:是⽆需等待确认应答,可以继续发送数据的最⼤值。
滑动窗口的控制:通常窗⼝的⼤⼩是由接收⽅的窗⼝⼤⼩来决定的。
累计确认:只要发送⽅收到了ACK700确认应答,就意味着700之前的所有数据「接收⽅」都收到了。
流量控制
TCP 流量控制的基本原理是使⽤滑动窗⼝机制
1. 接收窗⼝:接收⽅维护⼀个接收窗⼝,表示可以接收的数据段的范围。窗⼝⼤⼩可以根据接收⽅的处理能⼒进 ⾏调整。
2. 通告窗⼝⼤⼩:接收⽅通过 TCP 报⽂中的确认信息,通告当前的接收窗⼝⼤⼩给发送⽅。发送⽅会根据这个 窗⼝⼤⼩来控制发送数据的速率。
3. 窗⼝滑动:随着接收⽅处理数据的能⼒,窗⼝可以向前滑动。接收⽅可以通告更⼤的窗⼝,表示它可以接收更 多的数据。
4. 发送速率控制:发送⽅会根据接收⽅通告的窗⼝⼤⼩来控制发送数据的速率。如果接收窗⼝变⼩,表示接收⽅ 的处理能⼒减弱,发送⽅会减慢发送速率,避免数据拥塞。
5. 动态调整:TCP 流量控制是动态的,适应⽹络和接收⽅的变化。如果⽹络拥塞或接收⽅的处理速度变慢,流 量控制可以适时地减少发送速率。
拥塞控制
拥塞控制通过 拥塞窗⼝ 来防⽌过多的数据注⼊⽹络
拥塞窗⼝ cwnd 是发送⽅维护的⼀个状态变量,根据⽹络拥塞程度⽽变化。
发送窗⼝的值是 swnd = min(cwnd, rwnd) ,也就是拥塞窗⼝和接收窗⼝中的最⼩值。
⽹络中没有出现拥塞,cwnd增⼤,出现拥塞,cwnd减⼩。
过程
1. 慢启动:指数性的增⻓
2. 拥塞避免:超过阈值由指数增长变线性增长
3. 拥塞发⽣:
超时重传:阈值变一半,重新慢启动//很堵了,堵到报文传不过去或者收不到ack
快速重传: cwnd = cwnd/2;ssthresh = cwnd;进⼊快速恢复算法,有点堵,只是发的报文丢了,至少还收到接受方的三个ack
4. 快速恢复
1. 拥塞窗⼝ cwnd = ssthresh + 3 ( 3 的意思是确认有 3 个数据包被收到了);
2. 重传丢失的数据包;
3. 如果再收到重复的 ACK,那么 cwnd 增加 1;
4. 如果收到新数据的 ACK 后,把 cwnd 设置为第⼀步中的 ssthresh 的值,原因是该 ACK 确认了新的数据,说明从 duplicated ACK 时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进⼊拥塞避免状态;
超时重传图
快速重传与快速恢复图
UDP
TCP与UDP的区别
1、连接
TCP是⾯向连接的,在传输前需要三次握⼿建⽴连接。
UDP不需要连接,直接发送数据包,没有连接建⽴和关闭的过程。
2、服务形式
TCP是⼀对⼀的通信。在TCP连接中,⼀台客户端与⼀台服务器之间建⽴⼀条连接,进⾏双向通信。
UDP可以是⼀对⼀、⼀对多或多对多的通信。UDP是⽆连接的,⼀个UDP包可以被⼴播到多个⽬标主机,或
者从多个源主机接收UDP包。这使得UDP适⽤于多播和⼴播应⽤。
3、可靠性
TCP保证数据可靠交付,拥有确认应答和重传机制,⽆重复、不丢失、按序到达;
UDP尽可能交付,发送数据后不会关⼼数据包是否成功到达接收⽅,不会进⾏重传,不保证可靠性。
4、流量控制和拥塞控制
TCP拥有流量控制、拥塞控制,确保数据发送的速率不会超过接收⽅的处理能⼒,并防⽌⽹络拥塞。
UDP不进⾏流量控制和拥塞控制,数据发送的速率不受限制。
5、⾸部开销
TCP的⾸部⼤⼩通常为20字节,但在选项字段被使⽤的情况下,可能会更⼤。TCP⾸部包含源端⼝号、⽬标端
⼝号、序列号、确认号、窗⼝⼤⼩、校验和等字段。
UDP的⾸部⼤⼩固定为8字节。UDP⾸部包含源端⼝号、⽬标端⼝号、包⻓度和校验和字段(各16位)。
6、传输⽅式
TCP基于字节流,没有边界,但是保证传输顺序和可靠性;
UDP继承了IP层特性,基于数据包,有边界可能出现乱序和丢包。
7、分⽚⽅式
TCP数据⼤于MSS时会在TCP层将数据进⾏分⽚传输,到达⽬的地后同样在传输层进⾏合并,如果有某个⽚丢失则
只需要重传丢失的分⽚即可;
UDP数据⼤于MTU时会在IP层分⽚,则会在IP层合并,如果某个IP分⽚丢失,⽬标主机收到后,在 IP 层组装完数
据,接着再传给传输层。
3. 网络层
IP
分类
特殊地址
主机号全0:表示该网络
主机号全1:表示该网络下所有主机
127.0.0.1:回环
一个网段主机数=2^主机号位数-2
IP分⽚与重组
子网掩码与CIDR
子网掩码(Subnet Mask)
子网掩码用于将一个IPv4地址划分为 网络部分 和 主机部分。子网掩码与IPv4地址一样,长度为32位,用来区分同一网络内的设备和不同网络之间的设备。
CIDR(无类别域间路由)
CIDR 是一种更灵活的IP地址划分方法,它不依赖于传统的A、B、C类网络划分,而是使用 前缀长度 来表示网络部分。
CIDR表示法:
- CIDR使用IP地址后跟斜杠和一个数字的形式表示,例如
192.168.1.10/24
。这里的/24
表示前24位是网络部分,相当于子网掩码255.255.255.0
。 - 该数字称为 前缀长度,表示网络部分占用的位数。
子网划分(Subnetting)
子网划分 是将一个网络划分为多个子网络(子网)的过程,常常使用子网掩码或CIDR来完成。通过划分子网,可以更有效地利用IP地址,减少地址浪费,并增强网络管理的灵活性。
子网划分的步骤:
- 确定网络部分:根据业务需求,决定网络部分需要多少位。例如,
/24
表示网络部分占24位。 - 主机部分:剩余位数为主机部分。例如在
/24
中,剩下的8位用来分配主机地址,因此该子网中最多可以容纳 28−2=2542^8 - 2 = 25428−2=254 台主机(去掉网络地址和广播地址)。
IPv4 vs IPv6
路由与路由协议
静态路由与动态路由
静态路由 是由网络管理员手动配置的路由条目,它指定了从一个网络到另一个网络的固定路径。静态路由通常应用在网络结构较为简单、变化不频繁的网络中。
动态路由 是通过路由协议在路由器之间自动交换路由信息的机制。路由器根据这些动态更新的信息构建和更新其路由表,确保在网络拓扑变化时能够自动调整路由。
ARP
ARP(Address Resolution Protocol,地址解析协议)链路层协议,用于在局域网(如以太网)中通过IP地址获取对应的MAC地址。以下是ARP协议的详细知识点:
1. ARP的作用
- IP地址与MAC地址的映射:ARP用于将网络层的IP地址转换为链路层的MAC地址。由于IP地址是逻辑地址,而数据链路层依赖物理地址(如MAC地址)来进行数据传输,ARP通过广播的方式获取目标IP地址对应的MAC地址。
2. ARP的工作原理
- ARP请求(ARP Request):当主机A需要与同一网络中的主机B通信时,主机A会发送ARP请求广播,内容包含主机A的IP地址和B的IP地址,询问“谁是B的MAC地址?”。
- ARP响应(ARP Reply):拥有目标IP地址(如主机B)的设备会回应该请求,并将自己的MAC地址发送回主机A。ARP响应是单播的,只有发起ARP请求的主机可以接收。
- 缓存ARP结果:为了提高效率,主机通常会将获取的IP地址与MAC地址的映射关系存储在ARP缓存表中,并设置一个超时时间,避免频繁的ARP请求。
3. ARP和其他协议的关系
- ARP与IPv4:ARP是IPv4网络中不可或缺的协议,但在IPv6中被邻居发现协议(NDP)取代。
- ARP与DHCP:DHCP为主机动态分配IP地址,而ARP确保主机知道如何将IP地址解析为MAC地址进行通信。
- ARP与ICMP:ARP工作在网络层,但并不像ICMP那样直接用于检测网络状态。ICMP更多用于网络诊断(如ping),而ARP是为了实际的数据传输。
动态路由协议:RIP、OSPF、BGP
NAT
NAT(网络地址转换,Network Address Translation) 是一种在路由器或防火墙上应用的技术,用于在局域网(LAN)和广域网(WAN)之间转换IP地址,通常是在多个设备共享一个公共IP地址访问外部网络时使用。
NAT 的主要作用是解决 IPv4 地址不足的问题,同时提供了一定的网络安全性。它通过在私有网络和公共网络之间转换IP地址,使多个设备可以通过一个或少量的公共IP地址访问外部网络。
1. NAT 的类型
1.1. 静态NAT(Static NAT)
- 定义:静态NAT是将一个内部的私有IP地址映射到一个外部的公共IP地址。这个映射是固定的,即一个内部IP地址总是对应同一个外部IP地址。
- 应用场景:通常用于需要从外部网络(互联网)访问内部网络的特定设备(如服务器),保持设备拥有固定的公网IP地址。
- 例子:内网的服务器
192.168.1.10
始终映射到公共IP203.0.113.10
,外部用户通过访问203.0.113.10
来连接内部服务器。
1.2. 动态NAT(Dynamic NAT)
- 定义:动态NAT使用一个公共IP地址池,动态地将内部网络中的私有IP地址映射到外部网络中的公共IP地址。每当一个内部设备需要访问外部网络时,NAT设备会从公共IP池中分配一个可用的公网IP地址。
- 应用场景:通常用于内部设备较多,但只有部分设备同时需要访问外部网络的场景。
- 例子:内网中的设备
192.168.1.10
和192.168.1.20
可以通过 NAT 设备分别映射到公共IP203.0.113.10
和203.0.113.11
,但这些映射是动态的,随着时间的变化可能会更改。
1.3. PAT(端口地址转换,Port Address Translation)/NAT Overload
- 定义:PAT 是动态NAT的扩展版本,也被称为 NAT Overload,它不仅转换IP地址,还转换源端口号。这允许多个内部设备通过一个公共IP地址访问外部网络。
- 应用场景:最常用的NAT类型,广泛应用于家庭路由器和公司网络,允许多个内部设备共享一个公共IP地址进行互联网访问。
- 例子:内网中的设备
192.168.1.10:5000
和192.168.1.20:6000
共享公共IP203.0.113.10
,并通过不同的端口号来区分不同的内部设备。即使只有一个公共IP地址,NAT设备可以通过端口号将数据包正确路由到相应的内部设备。
2. NAT 的工作原理
NAT 的基本工作过程包括以下几步:
- 出站流量(从内网到公网):
- 内部设备使用私有IP地址发送请求到外部网络。
- NAT设备接收到请求后,将内部设备的私有IP地址转换为公共IP地址,并可能转换端口号(PAT),然后将请求转发到目标设备。
- 入站流量(从公网到内网):
- 外部设备的响应数据包到达NAT设备,NAT设备通过查找映射表,将公共IP地址(以及端口号)转换回相应的内部私有IP地址(和端口号),然后将数据包转发回原始内部设备。
4. 应用层协议
-
HTTP/HTTPS
1.HTTP过程
输入url,解析url
1.协议http、https的区别;HTTPS就是在HTTP与TCP之间增加了SSL/TSL安全传输层
2.格式:协议//主机:端口/路径;
3.HTTP版本:1.0和1.1
4.HTTP/1.1:
1. 持久连接:为了解决 HTTP/1.0 每次请求都需要建⽴新的连接的问题, HTTP/1.1 持久连接,只
要客户端和服务器任意⼀端没有明确提出断开连接,则保持TCP连接状态。
本地解析域名,如果没有向DNS服务器进行域名解析获取ip地址
1.是什么/为什么
2.DNS的过程
3.根域名服务器
向服务器请求http链接
1.http使用的是tcp,3次握手
2.请求方式get/post
服务器返回
1.常见状态码200/300/400/
2.cookies是什么
断开链接
1. 4次挥手
HTTP 1.1 vs 2.0 vs 3.0
请求方法
Cookie\Session \Token
Cookie、Session 和 Token 是在网络应用中常用的三种用户身份验证和会话管理技术。它们的作用都是为了解决无状态的 HTTP 协议无法保存用户状态的问题,确保用户在多个请求之间能够保持登录或会话状态。下面详细介绍它们的区别、工作原理及应用场景。
1. Cookie
定义:
- Cookie 是存储在用户浏览器中的一小段文本数据,用于在客户端和服务器之间传递信息。它主要用于存储会话信息、用户偏好设置等,以保持用户的状态。
工作原理:
- 服务器将 Cookie 信息存储在用户的浏览器中,之后每次用户向服务器发送请求时,浏览器都会自动携带该 Cookie 信息。
- Cookie 包含键值对,可以设置生存时间(即有效期)和作用域(如某个域名或路径)。
特点:
- 存储位置:客户端(浏览器)。
- 存储大小:通常每个 Cookie 的大小限制为 4KB。
- 安全性:Cookie 默认是明文存储的,除非使用加密方式。可以通过设置
Secure
标志(仅在 HTTPS 连接中传输)或HttpOnly
标志(防止 JavaScript 访问)来提升安全性。 - 生命周期:可以设置为会话 Cookie(浏览器关闭时删除)或持久 Cookie(根据指定的过期时间删除)。
应用场景:
- 保持登录状态:保存用户的登录信息,例如 "记住我" 功能。
- 追踪用户行为:用于广告或分析工具来追踪用户在网站上的行为。
- 存储用户偏好:如语言设置、购物车内容等。
优点:
- 简单易用:轻量级,使用方便,浏览器自动管理。
- 跨页面传递数据:可以在同一网站的不同页面之间传递用户信息。
缺点:
- 不安全:如果没有进行加密或使用 HTTPS,Cookie 很容易被劫持或篡改。
- 数据存储有限:每个 Cookie 的大小和数量都有严格限制,通常不能超过 4KB。
- 用户可禁用:用户可以选择禁用浏览器中的 Cookie,从而影响功能的正常使用。
2. Session
定义:
- Session 是服务器端用来存储用户会话信息的机制。每当用户与服务器建立连接时,服务器会为该用户生成一个唯一的 Session ID,用于在服务器端存储用户的会话数据。
工作原理:
- 用户首次访问服务器时,服务器会创建一个会话,并生成一个唯一的 Session ID。该 ID 会存储在客户端的 Cookie 中,随后的每次请求都会携带这个 ID。
- 服务器根据该 Session ID 来查找用户的会话数据,确保用户在多次请求中保持状态。
- Session 的存储一般在服务器的内存或数据库中。
特点:
- 存储位置:服务器端。
- 存储大小:没有严格的大小限制,因为数据存储在服务器上。
- 安全性:相比 Cookie 更加安全,因为数据存储在服务器端,客户端只携带一个 Session ID。
- 生命周期:通常 Session 在一段时间(如 30 分钟)内没有活动时会过期,也可以手动销毁会话(如用户注销时)。
应用场景:
- 用户登录状态管理:存储用户登录后的信息,确保在整个网站的多个页面之间保持用户的登录状态。
- 购物车管理:在电子商务网站中,服务器可以通过 Session 追踪用户的购物车内容。
- 数据存储:存储一些临时的用户信息,如表单数据、用户操作历史等。
优点:
- 安全性较高:数据存储在服务器端,客户端无法直接访问和修改。
- 适用于敏感信息:由于信息不存储在客户端,适合存储敏感信息(如用户身份验证数据)。
缺点:
- 消耗服务器资源:由于所有的会话数据都存储在服务器端,随着用户的增加,服务器的内存消耗也会增加。
- 依赖于 Cookie:虽然 Session 数据存储在服务器上,但仍然需要通过 Cookie 或 URL 参数传递 Session ID。
3. Token
定义:
- Token 是一种用户身份验证机制,它通常是一个加密字符串,包含了用户的信息。Token 是无状态的,服务器不存储会话数据,所有会话信息都包含在 Token 本身。
工作原理:
- 当用户登录成功后,服务器会生成一个 Token 并返回给客户端。客户端在随后的请求中携带这个 Token(通常放在 HTTP 头部 Authorization 字段中),服务器通过验证 Token 来识别用户身份。
- Token 通常是 JWT(JSON Web Token),它由三部分组成:Header(头部)、Payload(有效载荷,包含用户信息)和 Signature(签名,用于验证 Token 的完整性)。
特点:
- 存储位置:客户端(可以存储在 Cookie、LocalStorage 或 SessionStorage 中)。
- 存储大小:相对较小,因为 Token 是一个字符串。
- 安全性:Token 通常是加密和签名的,无法被篡改。同时,Token 可以通过设置过期时间来提高安全性。
- 无状态性:Token 本身包含了用户信息,服务器不需要保存会话状态,因此更适合分布式系统。
应用场景:
- API 认证:Token 被广泛应用于 API 认证,特别是移动应用或前后端分离的应用中。
- OAuth 2.0:Token 在 OAuth 2.0 协议中用于授权和身份验证。
- 单点登录(SSO):在多个系统之间共享登录状态时,Token 是常见的解决方案。
优点:
- 无状态:服务器不需要存储会话数据,适合大规模、分布式的应用系统。
- 跨平台:Token 可以很方便地用于 Web、移动应用、API 调用等场景。
- 灵活性强:可以在多个系统之间传递并进行身份验证。
缺点:
- 安全性依赖传输方式:如果 Token 以不安全的方式传输(如未加密的 HTTP),可能会被劫持。因此,需要使用 HTTPS 来保证安全。
- Token 失效管理复杂:由于 Token 是无状态的,服务器无法主动使某个 Token 失效,除非 Token 自身设置了过期时间。
4. Cookie、Session 和 Token 的对比
特性 | Cookie | Session | Token |
---|---|---|---|
存储位置 | 客户端(浏览器) | 服务器 | 客户端 |
存储大小 | 4KB 限制 | 由服务器存储,理论上无限制 | 通常很小,取决于内容 |
安全性 | 较低,需加密 | 较高,数据在服务器端 | 较高,通常加密和签名 |
生命周期 | 可以设置过期时间 | 一般在会话结束或超时后过期 | 可以设置过期时间 |
服务器资源占用 | 无需占用 | 需要占用服务器资源 | 无需占用,服务器无状态 |
跨平台支持 | 通常仅适用于浏览器环境 | 仅适用于 Web 应用 | Web、移动端、API、前后端分离 |
适用场景 | 保存用户状态、记住登录、跟踪行为 | 用户登录状态、临时数据存储 | API 认证、OAuth、SSO、跨平台应用 |
SSL/TLS加密
SSL/TLS 的核心是通过对称加密、非对称加密、数字签名和证书验证等技术,确保客户端和服务器之间的通信安全。
SSL/TLS 的通信过程(握手过程):
-
客户端Hello:
- 客户端向服务器发送一个
Client Hello
消息,包含客户端支持的加密算法、TLS 版本号、生成的随机数等信息。
- 客户端向服务器发送一个
-
服务器Hello:
- 服务器收到
Client Hello
后,选择一个双方都支持的加密算法,并发送Server Hello
消息,包含服务器选择的加密算法、服务器的数字证书、生成的随机数等。
- 服务器收到
-
服务器证书验证:
- 客户端收到服务器的数字证书后,使用数字证书中的公钥验证服务器的身份,确保它是真实可信的服务器。
-
密钥生成:
- 客户端使用服务器公钥加密一个“预主密钥”(Pre-Master Secret)并发送给服务器,服务器用自己的私钥解密这个预主密钥。
- 客户端和服务器根据约定的加密算法,使用
Client Hello
和Server Hello
中的随机数以及预主密钥,生成一个对称密钥,用于之后的通信加密。
-
握手完成:
- 双方用对称密钥加密传输的数据,进行加密的消息交换。
- 通信双方确认握手成功后,开始进行加密数据传输。
加密技术的应用:
- 对称加密:用于加密传输的数据,效率较高。常见算法包括 AES、DES 等。
- 非对称加密:用于传输对称密钥,保证密钥的安全性。常见算法包括 RSA、ECDSA 等。
- 数字签名:用于验证通信内容的完整性和服务器身份,确保信息未被篡改。
- 数字证书:由受信任的证书颁发机构(CA)签发,用于验证服务器的身份,防止中间人攻击。
DNS
使用容易记忆的域名替换IP
1.域名解析:域名->IP的过程
2.DNS属于应用层
DNS解析过程
1. 先查询浏览器缓存。
2. 缓存中没有,查询本地的Host⽂件。
3. Host⽂件没有则会向本地的DNS服务器查询。
4. 如果本地DNS解析器有该域名的ip地址,就会直接返回,如果没有会向根DNS服务器发出查询请求。根DNS服务器并不负责解析域名,但它能告诉本地DNS解析器应该向哪个顶级域的DNS服务器继续查询。
5. 本地DNS解析器接着向指定的顶级域名DNS服务器发出查询请求。顶级域DNS服务器也不负责具体的域名解
析,但它能告诉本地DNS解析器应该前往哪个权威DNS服务器查询下⼀步的信息。
6. 本地DNS解析器最后向权威DNS服务器发送查询请求。
7. 本地DNS解析器将收到的IP地址返回给浏览器,并且还会将域名解析结果缓存在本地。
8. 浏览器发起连接。
查询方式
递归查询
在递归查询中,DNS客户端(通常是本地DNS解析器)向上层DNS服务器(如根域名服务器、顶级域名服务器)发起查询请求,并要求这些服务器直接提供完整的解析结果。递归查询的特点是,DNS客户端只需要发送⼀个查询请求,然后等待完整的解析结果。上层DNS服务器会⾃⾏查询下⼀级的服务器,并将最终结果返回给DNS客端。
迭代查询
在迭代查询中,DNS客户端向上层DNS服务器发起查询请求,但不要求直接提供完整的解析结果。相反,DNS客户端只是询问上层服务器⼀个更⾼级的域名服务器的地址,然后再⾃⾏向那个更⾼级的服务器发起查询请求,以此类推,直到获取完整的解析结果为⽌。递归查询适合普通⽤户和客户端,⽽迭代查询适⽤于DNS服务器之间的通信。
DNS缓存
FTP
SMTP
POP3
IMAP
5. 网络编程
Socket编程
1. Socket 的基本概念
Socket 定义:
- Socket 是一种进程间通信的抽象接口,通常指的是 TCP/IP 协议栈中的通信端点。它既可以作为客户端,也可以作为服务器。
- Socket 的创建和使用流程:
- 创建 Socket:通过系统调用创建一个套接字。
- 绑定地址(服务器端):将 Socket 绑定到一个具体的网络地址(IP 地址和端口号)。
- 监听连接(服务器端):监听来自客户端的连接请求。
- 连接服务器(客户端):客户端向服务器发起连接。
- 数据传输:双方通过 Socket 进行数据传输。
- 关闭连接:结束通信,关闭 Socket。
Socket 类型:
- 流式套接字(TCP Socket):基于 TCP 协议,提供可靠的字节流通信。
- 数据报套接字(UDP Socket):基于 UDP 协议,不保证可靠性,适合对速度要求高的场景。
2. 阻塞与非阻塞 Socket
阻塞模式:
- 在阻塞模式下,某些操作(如
connect()
、accept()
、recv()
、send()
)会让程序暂停执行,直到该操作完成。- 阻塞连接(accept):服务器调用
accept()
时会阻塞,直到有客户端连接。 - 阻塞读写(recv/send):调用
recv()
和send()
时会阻塞,直到数据传输完成。
- 阻塞连接(accept):服务器调用
非阻塞模式:
- 在非阻塞模式下,Socket 操作立即返回,如果操作无法完成,则返回一个错误,表示暂时无法执行(例如读操作无数据时会返回错误)。
- 优点:程序不会因为等待数据或连接而挂起,可以继续执行其他任务。
- 缺点:需要反复检查 Socket 状态,增加了编程复杂度。
TCP Socket 与 UDP Socket
TCP Socket
- 协议特性:TCP 是一种面向连接的、可靠的协议。通信前需要建立连接(三次握手),并保证数据的可靠性和顺序。
- 实现方式:
- 服务器端:
- 创建 Socket (
socket()
),指定 TCP 协议类型。 - 绑定 IP 地址和端口号 (
bind()
)。 - 监听连接请求 (
listen()
)。 - 接受连接 (
accept()
),建立连接。 - 传输数据 (
recv()
和send()
)。 - 关闭连接 (
close()
)。
- 创建 Socket (
- 客户端:
- 创建 Socket。
- 连接服务器 (
connect()
)。 - 发送和接收数据。
- 服务器端:
UDP Socket
- 协议特性:UDP 是一种无连接、不可靠的协议,数据报文发送不需要建立连接,不保证数据顺序和完整性。
- 实现方式:
- 服务器端:
- 创建 Socket,指定 UDP 协议类型。
- 绑定 IP 地址和端口号。
- 接收数据 (
recvfrom()
)。 - 发送数据 (
sendto()
)。 - 关闭 Socket。
- 客户端:
- 创建 Socket。
- 发送和接收数据。
- 无需建立连接。
- 服务器端:
TCP 与 UDP 的区别
特性 | TCP | UDP |
---|---|---|
是否连接 | 面向连接,需要建立连接 | 无连接,不需要连接 |
数据传输可靠性 | 可靠,保证数据顺序和完整性 | 不可靠,可能丢包、乱序 |
传输效率 | 较低(需要确认、重传机制) | 高(无确认、重传机制) |
适用场景 | 文件传输、HTTP、SMTP 等 | 实时视频、语音、DNS 查询 |
I/O 多路复用
I/O 多路复用 是一种在一个线程中监控多个 I/O 事件的方法,尤其在处理大量并发连接时非常有效。它允许一个进程同时等待多个文件描述符(如多个 Socket)的事件,任何一个文件描述符有事件发生时,程序即可进行处理。常用的多路复用机制有 select
、poll
和 epoll
。
select
- 工作原理:
select
通过轮询所有文件描述符,判断是否有 I/O 事件发生(如读或写操作)。一旦发现有事件发生,程序可以进行处理。 - 缺点:
- 文件描述符数量有限(通常 1024 或 2048)。
- 轮询效率低,随着文件描述符数量的增加,性能下降。
poll
- 工作原理:
poll
和select
类似,但它没有文件描述符数量限制。poll
使用一个数组来保存文件描述符,判断是否有 I/O 事件。 - 缺点:和
select
一样,它也使用轮询,所有文件描述符都要遍历一次,性能较差。
epoll
- 工作原理:
epoll
是 Linux 下的高效 I/O 多路复用机制,和select
、poll
不同,epoll
不需要遍历所有文件描述符。它通过事件通知机制,只监控发生变化的文件描述符,极大地提高了效率。- epoll_create():创建一个 epoll 实例。
- epoll_ctl():向 epoll 实例中添加、删除或修改监听的文件描述符。
- epoll_wait():等待事件的发生,并处理已准备好的文件描述符。
- 优点:性能高,适合处理大量并发连接,特别是长连接场景。
I/O 多路复用对比
特性 | select | poll | epoll |
---|---|---|---|
文件描述符限制 | 有限制(1024/2048) | 无限制 | 无限制 |
工作方式 | 轮询所有文件描述符 | 轮询所有文件描述符 | 事件驱动,仅检查变化事件 |
性能 | 随着文件描述符增加下降 | 随着文件描述符增加下降 | 高效,适合大量连接 |
应用场景 | 小规模网络应用 | 中小规模网络应用 | 大规模并发应用 |
高并发与多线程网络编程
- 高并发:指系统能够同时处理大量的请求。在高并发场景下,系统通过多线程或异步模型,充分利用多核 CPU 和 I/O 资源,以提高响应速度和吞吐量。
- 多线程:每个线程可以独立执行一段代码,多线程编程允许程序同时处理多个任务(如多个客户端请求),从而提高并发性能。
2. C++中常用的多线程库
3. Reactor 和 Proactor 设计模式
在网络编程中,Reactor 和 Proactor 是两种经典的 I/O 事件驱动设计模式,广泛应用于高并发服务器的架构设计。
Reactor 模式
- 定义:Reactor 模式是一种事件驱动设计模式,在这种模式下,主线程(或 I/O 线程)负责监听多个文件描述符上的事件(如读、写、连接等),当有事件发生时,主线程将事件分发给处理器线程(或处理回调函数)。
- 工作原理:
- I/O 多路复用(如
select
、poll
、epoll
)监听多个 I/O 事件。 - 事件发生时,主线程触发回调函数或将事件交给工作线程处理。
- 事件处理是同步的,即当事件触发时,实际的 I/O 操作(如读写数据)在用户线程中完成。
- 常用于高并发网络服务器(如 Nginx)中。
- I/O 多路复用(如
Proactor 模式
-
定义:Proactor 模式也是一种事件驱动设计模式,但与 Reactor 不同的是,I/O 操作由操作系统或底层库完成,事件处理器只负责处理完成的 I/O 操作。
-
工作原理:
- 应用程序向操作系统发起异步 I/O 操作(如读、写)。
- 操作系统执行 I/O 操作,操作完成后通知应用程序。
- 应用程序的回调函数处理已完成的 I/O 操作。
特点:
- I/O 操作是异步的,操作系统负责管理 I/O,应用程序只处理完成的 I/O 事件。
- 提升了系统的并发能力,因为 I/O 操作不阻塞线程。
- 常用于异步 I/O 框架(如 Windows 的 IOCP、Boost.Asio)。
4. 线程池的实现与使用
线程池定义
- 线程池 是一种优化多线程应用性能的技术,它通过预创建一定数量的线程,并将任务提交给线程池中的空闲线程执行。线程池减少了频繁创建和销毁线程的开销。
线程池的工作流程:
- 初始化:创建若干个工作线程,并将它们放入线程池。
- 提交任务:当有任务需要执行时,任务被添加到任务队列中。
- 线程执行任务:线程池中的空闲线程从任务队列中取出任务并执行。
- 线程重用:任务执行完毕后,线程回到线程池继续等待新的任务。
线程池的优点:
- 避免频繁创建和销毁线程,减少资源消耗。
- 更好地管理系统资源,防止因创建过多线程而导致系统负载过高。
- 提高并发能力,多个任务可以并行执行。
C++ 实现线程池的基本步骤:
- 创建一个任务队列,用于存放需要执行的任务。
- 创建若干个工作线程,从任务队列中取出任务并执行。
- 使用互斥锁和条件变量,保证线程之间的同步与通信。
简易线程池实现示例:
#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
class ThreadPool {
public:
ThreadPool(size_t threads);
~ThreadPool();
void enqueue(std::function<void()> task);
private:
std::vector<std::thread> workers;
std::queue<std::function<void()>> tasks;
std::mutex queue_mutex;
std::condition_variable condition;
bool stop;
};
ThreadPool::ThreadPool(size_t threads) : stop(false) {
for (size_t i = 0; i < threads; ++i) {
workers.emplace_back([this] {
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(this->queue_mutex);
this->condition.wait(lock, [this] {
return this->stop || !this->tasks.empty();
});
if (this->stop && this->tasks.empty()) {
return;
}
task = std::move(this->tasks.front());
this->tasks.pop();
}
task();
}
});
}
}
ThreadPool::~ThreadPool() {
{
std::unique_lock<std::mutex> lock(queue_mutex);
stop = true;
}
condition.notify_all();
for (std::thread &worker : workers) {
worker.join();
}
}
void ThreadPool::enqueue(std::function<void()> task) {
{
std::unique_lock<std::mutex> lock(queue_mutex);
tasks.push(std::move(task));
}
condition.notify_one();
}
int main() {
ThreadPool pool(4);
pool.enqueue([] {
std::cout << "Task 1 executing" << std::endl;
});
pool.enqueue([] {
std::cout << "Task 2 executing" << std::endl;
});
return 0;
}
6. 网络安全
- 加密与认证
- 对称加密 vs 非对称加密
- RSA、AES、TLS的工作原理
- 网络攻击与防护
- 常见网络攻击:DDoS、MITM(中间人攻击)、XSS、SQL注入
- 防护机制:防火墙、VPN、IDS/IPS
- HTTPS与SSL/TLS
- 公钥基础设施(PKI)
- 证书颁发与验证
7. 分布式系统相关网络知识
负载均衡算法
1. 轮询法(Round Robin)
-
定义:轮询法是最简单的负载均衡算法,按照固定的顺序将请求依次分配给每个服务器。
-
工作原理:
- 假设有三个服务器(A、B、C),第一个请求分配给 A,第二个请求分配给 B,第三个请求分配给 C,接着再回到 A,依次循环。
优点:
- 简单易用,无需记录服务器的状态。
- 适用于负载较为均衡的场景。
缺点:
- 未考虑服务器的实际性能或当前负载,如果服务器性能不同或存在负载差异,可能导致某些服务器过载。
2. 加权轮询法(Weighted Round Robin)
-
定义:加权轮询法是在轮询法的基础上加入了权重的概念,服务器根据权重分配更多的请求,适用于服务器性能不同的场景。
-
工作原理:
- 每台服务器会分配一个权重,性能高的服务器分配较大的权重,接收到的请求也更多。例如,服务器 A 的权重为 3,B 的权重为 1,C 的权重为 2,则 A 会处理更多的请求。
优点:
- 可以根据服务器的性能动态调整权重,保证高性能的服务器承载更多请求。
缺点:
- 实现相对复杂,且需要提前了解服务器的性能和负载状况。
3. 最少连接法(Least Connection)
-
定义:最少连接法将请求分配给当前处理连接最少的服务器。适用于请求处理时间长短不一的情况。
-
工作原理:
- 负载均衡器实时监控每台服务器上的连接数,并将新请求分配给连接数最少的服务器。
优点:
- 可以动态地分配负载,避免服务器过载。
缺点:
- 需要额外的计算开销,用于实时监控每台服务器的连接数。
4. 一致性哈希(Consistent Hashing)
-
定义:一致性哈希是一种分布式负载均衡算法,常用于分布式缓存系统或分布式存储系统中,保证数据和请求在服务器之间均衡分布,且在节点增减时对系统的影响最小。
-
工作原理:
- 将服务器和数据的哈希值映射到一个哈希环上,数据请求通过哈希值找到其对应的服务器。假设服务器下线,哈希环上只需重新分配与该服务器相邻的部分数据,其他服务器不会受到影响。
优点:
- 对于节点的增加和删除有良好的容忍性,避免了大规模的数据重新分配。
- 在分布式缓存场景下,减少了缓存失效带来的性能损失。
缺点:
- 实现较为复杂,尤其是在服务器哈希分布不均匀时,可能需要使用虚拟节点技术进行优化。
-
分布式系统的网络架构
- 微服务架构与SOA(面向服务架构)
-
RPC(远程过程调用)
- RPC原理与实现
- gRPC vs RESTful
8. 性能与优化
-
网络延迟与带宽
- 延迟、带宽、吞吐量的概念与关系
-
网络性能优化
- TCP优化(如窗口大小调整、Nagle算法)
- CDN(内容分发网络)
-
QoS(服务质量)
- 流量分类与优先级机制