OSI七层模型是什么?
他是一种网络通信模型,全称是开放系统互连参考模型。它将网络通信过程自上而下分为7个逻辑层,每一层都有其明确的职责
包括:应用层--->表示层--->会话层--->传输层--->网络层--->数据链路层--->物理层
应用层:面向用户的,提供网络接口,比如http、ftp、smtp等协议都工作在这一层。应用层是用户与网络交互的入口
表示层:主要负责数据管理通信双方的会话的格式转换、加解密和压缩。他确保不同系统之间的数据能够正确解析。
会话层:用于管理通信双方的会话,来建立、维护和终止会话连接。
传输层:提供端到端的数据传输服务,支持可靠传输(如TCP)和不可靠传输(如UDP),并进行端口号的区分
网络层:负责路径选择和逻辑地址(IP地址)的分配,实现跨网络的数据包传输,典型协议有IP、ICMP等
数据链路层:将网络层传来的数据封装成帧,负责物理地址(MAC地址)的识别和错误检测、确保相邻节点间的可靠传输
物理层:负责比特流的传输,包括光纤、网卡等物理介质,是硬件级别的传输层
发送端封装过程(自上而下):
┌──────────────┐
│ 应用层 │
│ [原始数据] │
└──────┬───────┘
↓
┌──────────────┐
│ 表示层 │
│ [编码/加密/压缩] │
└──────┬───────┘
↓
┌──────────────┐
│ 会话层 │
│ [会话控制信息] │
└──────┬───────┘
↓
┌──────────────┐
│ 传输层 │
│ [传输头 + 数据] │ ← 段(Segment)
└──────┬───────┘
↓
┌──────────────┐
│ 网络层 │
│ [IP头 + 段] │ ← 包(Packet)
└──────┬───────┘
↓
┌──────────────┐
│ 数据链路层 │
│ [帧头 + 包 + 帧尾] │ ← 帧(Frame)
└──────┬───────┘
↓
┌──────────────┐
│ 物理层 │
│ [比特流] │ ← 0/1 电信号或光信号
└──────────────┘
OSI七层模型每一层在处理数据时是怎么封装的?
某些层在向下一层传递数据时会添加自己的头部信息,少数还可能添加尾部信息,经过7层包装后最终形成完整的帧或比特流进行发送。
应用层产生一个原始数据,比如一个http请求;
表示层可能对数据进行编码、压缩、加密等,但封装不加额外头部,处理完再往下传
会话层来管理通信控制,一般不会显示添加头部
传输层将上层数据封装成一个段(segment),并添加传输层头部信息,如tcp/udp头,包括端口号、序列化等
网络层将传输层的段封装成一个包(package),添加网络层头部信息(如ip头,包含源ip和目标ip)
数据链路层将包封装成一个帧(frame),添加帧头和帧尾(包含MAC地址和CRC校验码)
物理层将帧转换为比特流(bits),通电光纤、电缆等传输出去
所以从发送端来看,整个数据封装流程是:
数据 → 段(Segment) → 包(Packet) → 帧(Frame) → 比特流(Bits)
在接收端整个过程会反过来解析,每层解析并剥离自己的头部,直到还原出最初的应用数据
┌────────────────────────────┐
│ 应用层(HTTP 协议) │
│ GET / HTTP/1.1 │
│ Host: example │
│ ... │ ← 原始 HTTP 请求数据
└────────────┬─────────────┘
↓
┌────────────────────────────┐
│ 表示层(编码/加密) │
│ HTTP 文本按 UTF-8 编码 │
│ (可能加密/压缩) │
└────────────┬─────────────┘
↓
┌────────────────────────────┐
│ 会话层(管理会话) │
│ 标记该会话的状态 │
│ (浏览器和服务器之间的连接)│
└────────────┬─────────────┘
↓
┌────────────────────────────┐
│ 传输层(TCP 协议) │
│ TCP 头部: │
│ 源端口:49152 │
│ 目标端口:80 │
│ 序列号、确认号、校验和等 │
│ + │
│ HTTP 请求数据 │ ← 形成“段 Segment”
└────────────┬─────────────┘
↓
┌────────────────────────────┐
│ 网络层(IP 协议) │
│ IP 头部: │
│ 源 IP:192.168.1.100 │
│ 目标 IP:93.184.216.34 │
│ TTL、协议号等 │
│ + │
│ TCP 段 │ ← 形成“包 Packet”
└────────────┬─────────────┘
↓
┌────────────────────────────┐
│ 数据链路层(如以太网) │
│ 帧头(Ethernet): │
│ 源 MAC:AA:BB:CC:DD:EE:01 │
│ 目标 MAC:AA:BB:CC:DD:EE:02│
│ 帧尾(CRC 校验) │
│ + │
│ IP 包 │ ← 形成“帧 Frame”
└────────────┬─────────────┘
↓
┌────────────────────────────┐
│ 物理层 │
│ 把帧转为比特流(电信号) │
│ 010101011010... │ ← 最终发送的“比特流 Bits”
└────────────────────────────┘
OSI七层模型中每层的常见协议?
层名 | 常见协议 |
---|---|
应用层 | HTTP、FTP、DNS、SMTP |
表示层 | SSL/TLS、JPEG、MPEG、ASCII |
会话层 | NetBIOS、RPC、SQL 会话、Named Pipes |
传输层 | TCP、UDP |
网络层 | IP、ICMP、ARP、IGMP |
数据链路层 | Ethernet、PPP、MAC、VLAN |
物理层 | RJ45、光纤、Wi-Fi、比特流 |
TCP/IP协议是什么?
OSI模型是理论参考模型,而TCP/IP是实际应用的协议体系,是一个协议族
核心协议包括:
TCP:传输控制协议,提供可靠的、面向连接的数据传输,确保数据完整、按序到达
IP:网际协议,负责寻址与路由,保证数据从源主机发送到目标主机
TCP/IP大致分为4层,其中:
应用层对应OSI的上三层(应用层、表示层、会话层):负责提供网络服务给用户,常见协议有HTTP\FTP\SMTP;
传输层对应OSI的传输层:提供端到端的通信服务,包括数据传输的可靠性和顺序,常见协议有TCP/UDP;
网络层对应OSI的网络层:负责数据包从源地址到目的地址的路由和转发,核心协议有IP\ICMP\ARP
网络接口层(链路层)对应OSI的数据链路层+物理层:负责主机和物理网络之间的数据传输,包含物理地址识别、帧封装和传输,常见技术有WIFI、Ethernet等
TCP/IP为什么只有4层?
只有四层是因为他是从实际网络协议实现出发设计的,更强调实用性和协议集成度,而不是像OSI模型那样从功能上严格划分为七层。
具体来说,TCP/IP将OSI的应用层、表示层、会话层合并为应用层,因为很多网络协议(如HTTP、FTP)本身就同时处理了数据格式、会话管理等功能,不需要再分层。
将OSI的数据链路层和物理层合并为网络接口层,因为在现实中,网卡和驱动往往一体完成物理层和数据链路层的任务,操作系统直接通过网卡驱动收发帧。
IP协议包含哪些字段?
ipv4(不含选项时报文最小是20字节,含选项时报文最大可达60字节)
字段名称 | 长度(位) | 说明 |
---|---|---|
Version | 4 | 协议版本号,IPv4 为 4 |
IHL | 4 | 首部长度 |
Type of Service | 8 | 服务类型(TOS)/DSCP |
Total Length | 16 | 数据报总长度 |
Identification | 16 | 标识分片 |
Flags | 3 | 分片标志 |
Fragment Offset | 13 | 分片偏移量 |
Time To Live (TTL) | 8 | 生存时间,防止死循环 |
Protocol | 8 | 上层协议类型(如 TCP 是 6) |
Header Checksum | 16 | IP 头校验和 |
Source IP Address | 32 | 源 IP 地址 |
Destination IP | 32 | 目标 IP 地址 |
Options(可选) | 可变 | 扩展字段(可选) |
示例:
45 00 00 3C AB CD 40 00 40 06 1A 2B C0 A8 01 0A AC 10 00 01
|字节偏移| 字段名称 | 长度(位) | 示例值(x) | 说明 |
| ----- | -------------------- | ----- | ------------- | -------------- |
| 0 | Version + IHL | 8 | `45` | 版本4 + 首部长度
| (5×4=20字节)
|
| 1 | Type of Service | 8 | `00` | TOS |
| 2-3 | Total Length | 16 | `00 3C` | 60 字节总长 |
| 4-5 | Identification | 16 | `AB CD` | 分片标识 |
| 6-7 | Flags + Fragment Off | 16 | `40 00` | 不分片,偏移为 0 |
| 8 | Time to Live | 8 | `40` | TTL = 64 |
| 9 | Protocol | 8 | `06` | TCP 协议 |
| 10-11 | Header Checksum | 16 | `1A 2B` | 校验和 |
| 12-15 | Source IP | 32 | `C0 A8 01 0A` | 192.168.1.10 |
| 16-19 | Destination IP | 32 | `AC 10 00 01` | 172.16.0.1 |
ipv6(报文是固定的40字节大小)字段更精简,结构更适应现代网络。
字段名称 | 长度(位) | 说明 |
---|---|---|
Version | 4 | 协议版本号,IPv6 为 6 |
Traffic Class | 8 | 流量类别(类似 IPv4 的 TOS) |
Flow Label | 20 | 流标签,用于标识数据流 |
Payload Length | 16 | 负载长度,不包括头部 |
Next Header | 8 | 下一个头部类型(类似 IPv4 的 Protocol) |
Hop Limit | 8 | 跳数限制,替代 TTL |
Source IP Address | 128 | 源 IPv6 地址 |
Destination IP | 128 | 目的 IPv6 地址 |
示例:
60 00 00 01 05 00 06 40
20 01 0D B8 00 00 00 00 00 00 00 00 00 00 00 01
24 08 84 0E 00 00 00 00 00 00 00 00 00 00 00 02
字节偏移 | 字段名称 | 长度(位) | 示例值(十六进制) | 说明 |
---|---|---|---|---|
0-3 | Version + TC + FL | 32 | 60 00 00 01 | 版本6,流量类0,流标签1 |
4-5 | Payload Length | 16 | 05 00 | 有效负载长度:1280 字节 |
6 | Next Header | 8 | 06 | TCP 协议 |
7 | Hop Limit | 8 | 40 | 跳数限制 64 |
8-23 | Source IP | 128 | 20 01 0D B8 00 00 00 00 00 00 00 00 00 00 00 01 | IPv6 源地址 |
24-39 | Destination IP | 128 | 24 08 84 0E 00 00 00 00 00 00 00 00 00 00 00 02 | IPv6 目的地址 |
Ipv4和Ipv6的区别?
ipv6是为了解决ipv4地址枯竭、安全性和效率问题而设计的下一代互联网协议,拥有更大的地址空间和更简洁的头部结构
区别点 | IPv4 | IPv6 |
---|---|---|
地址长度 | 32 位(4 字节) | 128 位(16 字节) |
地址表示 | 点分十进制,如:192.168.1.1 | 冒分十六进制,如:2001:0db8:85a3::8a2e:0370:7334 |
地址数量 | 约 43 亿个 | 理论上接近无限(2¹²⁸) 340万亿 |
报文头大小 | 最小 20 字节,最大 60 字节(含选项) | 固定 40 字节 |
NAT 支持 | 支持,需要解决地址不足问题 | 不需要 NAT,地址充足 |
广播方式 | 支持广播 | 不支持广播,改用多播(Multicast) |
配置方式 | 通常需要手动或 DHCP 配置 | 支持自动地址配置(SLAAC) |
安全支持 | 可选 IPsec | IPsec 是强制标准 |
兼容性 | 已广泛部署 | 正在逐步推广,不兼容 IPv4 |
IP中的子网掩码、网络地址、广播地址、主机地址都是什么?
在IP网络中,一个IP地址通常由两部分组成:网络部分和主机部分分,具体的划分由子网掩码决定。子网掩码是一串32位的二进制数,1表示网络位,0表示主机位,用来区分一个IP地址的网络部分和主机部分。其中1和0的数量由前缀长度决定,前缀长度是用来表示子网掩码中网络位长度的一个数字。
网络地址是将IP地址和子网掩码按位与的结果,即网络位全是1,主机位全是0,用于标识一个子网的起始地址,不可以分配给主机使用。
广播地址是在同一子网中,用于向该子网中所有主机发送数据的特殊地址,计算方式是将IP地址主机位全部置1。
主机地址是指介于网络地址和广播地址之间的IP地址,这些地址才可以真正分配给设备使用,是子网中真正可用的地址空间。
二进制表示 | 点分十进制 | |
---|---|---|
IP地址 | 11000000.10101000.00001010.00010010 | 192.168.10.18 |
子网掩码 | 11111111.11111111.11111111.00000000 | 255.255.255.0 |
网络地址 | 11000000.10101000.00001010.00000000 | 192.168.10.0 |
广播地址 | 11000000.10101000.00001010.11111111 | 192.168.10.255 |
主机地址范围 | 从192.168.10.1到192.168.10.254 | 可用主机IP地址范围 |
介绍下大端字节序和小端字节序?
大端字节序:数据的高位字节存放在内存的低地址,低位字节存放在高地址
高字节在前,低字节在后
网络协议(如TCP/IP)规定使用大端字节序,也成为网络字节序
32 位整数 0x12345678 存储顺序为:
地址低 → 高
0x12 0x34 0x56 0x78
小端字节序:数据的低位字节存放在内存的低地址,高位字节存放在高地址
低字节在前,高字节在后
x86架构的CPU默认使用小端字节序
32 位整数 0x12345678 存储顺序为:
地址低 → 高
0x78 0x56 0x34 0x12
字节序转换api <arpa/inet.h>
htonl()、htons():主机字节序---->网络字节序 (小/大端字节序 ----> 大端字节序)
ntohl()、ntohs():网络字节序----->主机字节序 (大端字节序 ----> 小/大端字节序)
....l:用于对32位(long类型)整数进行转换
...s:用于对16位(short类型)整数进行转换
uint32_t host_long = 0x12345678; // 32 位整数
uint16_t host_short = 0x1234; // 16 位整数
// 转换为网络字节序(大端)
uint32_t net_long = htonl(host_long);
uint16_t net_short = htons(host_short);
什么是 MAC 地址?
MAC地址是网卡在数据链路层的物理地址,用于在局域网内唯一标识每一台设备。
MAC地址由48位二进制(6字节)构成,通常写作6组十六进制,如:00:1A:2B:3C:4D:5E
。
前3字节是厂商编号,后3字节由厂商自定义,保证唯一。
MAC地址的作用:
MAC 地址用于局域网内设备之间的通信,是以太网中定位目标设备的关键。当一台设备发送数据时,会将目标设备的 MAC 地址写入数据帧头部,确保数据能够在局域网中准确送达目标网卡。
注意:如果只知道对方 IP 地址,系统会先通过 ARP 协议查询对应的 MAC 地址,然后再发送数据。
什么是NAT?
背景:ipv4公网地址是稀缺资源,数量有限,不够给世界上每一个设备都分一个唯一的公网ip
NAT(网络地址转换)是一种在路由器上实现的技术,用于在私有网络和公网之间转换IP地址,解决Ipv4地址不足的问题。
我们用一台路由器(或运营商设备)来分配一个公网 IP,所有连到这台路由器的设备(电脑、手机、电视等)用私有 IP(如 192.168.x.x
),但是内网设备使用的私有ip地址无法直接访问公网,所以需要通过 NAT 技术将私有ip统一转换成公网 IP 后才可以上网。
┌──────────────┐
│ Internet │
│ 公网服务器IP │
└─────┬────────┘
│
公网地址:Port
┌──────▼──────┐
│ 路由器/NAT │ ←←← 拥有一个公网 IP,如 203.0.113.1
└──┬────▲────┬┘
│ │ │
│ │ │
┌──────────▼┐ ┌─▼────────┐ ┌─────────▼┐
│ PC1 │ │ PC2 │ │ 手机 │
│ 192.168.1.2│ │192.168.1.3│ │192.168.1.4│
└───────────┘ └──────────┘ └──────────┘
内网设备 | NAT 映射关系(出网) | 外网服务器看到的是 |
---|---|---|
192.168.1.2:1234 | → 203.0.113.1:50001(NAT分配端口) | 请求来自 203.0.113.1:50001 |
192.168.1.3:2345 | → 203.0.113.1:50002 | 请求来自 203.0.113.1:50002 |
什么是DNS?
DNS(Domain Name System, 域名系统),是互联网中的地址解析服务,它的作用是将人类易读的域名(如www.example)转换成计算机能识别的IP地址(如98.131.216.24)。
为什么需要DNS?
因为用户访问网站更容易记住域名,但网络通信依赖ip地址,DNS就是负责做
"域名<--->IP"的映射,让我们可以用域名访问网站。相当于互联网的电话薄
DNS的工作流程:
-
用户在浏览器中输入网址(如
www.baidu
); -
操作系统先查本地缓存,有则直接用;
-
没有则向本地 DNS 服务器发起查询请求;
-
本地 DNS 若没有记录,则层层向根域名服务器 → 顶级域服务器 → 权威 DNS 服务器查询;
-
找到 IP 地址后返回,浏览器用这个 IP 去访问目标服务器。
查询时有两种方式:递归查询和迭代查询
递归查询:客户端(浏览器或操作系统)向本地DNS服务器请求解析域名,本地DNS服务器全权负责找出最终ip并返回,客户端只问一次,本地服务器背后可以多次跳转,对客户端友好、负担小,压力都在本地DNS服务器。
迭代查询:本地DNS服务器接收到客户端的请求后,会先向跟DNS查询,如果没查询到继续问DNS,DNS也没查到再去问权威DNS
-
本地 DNS 向根 DNS 查询:
“你知道
www.example
的 IP 吗?” -
根 DNS 回复:
“我不知道,但你可以去问
的 DNS 服务器。”
-
本地 DNS 接着问
DNS,
DNS 再说“你问权威 DNS 吧”...
-
从客户端视角来看 —— 我发了一个请求,本地 DNS 会“递归查到底”;
-
从本地 DNS 自己视角来看 —— 它是靠自己一步步 “迭代” 地去问根服务器、TLD 服务器、权威服务器,才拿到最终结果的。
客户端(你)
↓ 递归查询
本地 DNS
↓ 迭代查询
根服务器 → 返回 “去找 TLD”
↓
TLD服务器 → 返回 “去找 example 权威服务器”
↓
example 权威服务器 → 返回 www.example 的 IP 地址
Http常见状态码有哪些?
1xx(信息性状态码)
表示请求已被接收,需要继续处理。
-
100 Continue:客户端应继续发送请求的剩余部分。
2xx(成功状态码)
表示请求已成功被服务器接收、理解并处理。
-
200 OK:请求成功,响应中包含请求的数据(如 GET 请求)。
-
201 Created:请求成功且服务器创建了新资源(如 POST 请求)。
-
202 Accepted:请求已接受但尚未处理完成(异步任务)。
-
204 No Content:请求成功,但响应无内容(如 DELETE 请求)。
3xx(重定向状态码)
表示需要客户端进一步操作以完成请求。
-
301 Moved Permanently:资源已永久重定向到新 URL,浏览器会缓存。
-
302 Found:资源临时重定向到新 URL,浏览器不缓存。
4xx(客户端错误状态码)
表示客户端请求有错误。
-
400 Bad Request:请求语法错误,服务器无法理解。
-
401 Unauthorized:需要身份验证(如未登录)。
-
403 Forbidden:服务器拒绝请求(无权限)。
-
404 Not Found:请求的资源不存在。
-
405 Method Not Allowed:请求方法不被允许(如 GET 接口用 POST 访问)。
-
408 Request Timeout:请求超时。
-
429 Too Many Requests:请求频率过高(限流)。
5xx(服务器错误状态码)
表示服务器处理请求时出错。
-
500 Internal Server Error:服务器内部错误(如代码异常)。
-
502 Bad Gateway:代理服务器从上游服务器收到无效响应。
-
503 Service Unavailable:服务不可用(如过载或维护)。
-
504 Gateway Timeout:代理服务器等待上游服务器响应超时。
HTTP 请求中包含什么?
一个标准的 HTTP 请求由以下几部分组成:
<请求行> ← 命令 + 路径 + 协议版本
<请求头部> ← 一组键值对,描述客户端、格式、认证等
<空行> ← 用于分隔头部和请求体
<请求体>(可选) ← 主要用于 POST/PUT 请求,包含实际数据
HTTP 响应中包含什么?
<状态行> ← 响应结果的状态代码、原因短语、HTTP 版本
<响应头部> ← 一组键值对,说明服务器、响应体格式等信息
<空行> ← 分隔头部和响应体
<响应体>(可选) ← 实际的响应内容(HTML、JSON、图片等)
HTTP 请求头中包含什么?
请求头字段 | 作用说明 | 示例 |
---|---|---|
Host | 指定目标服务器的主机名和端口(HTTP/1.1 必需) | Host: www.example |
User-Agent | 客户端信息(浏览器或程序名称/版本) | User-Agent: Mozilla/5.0 ... |
Accept | 客户端可接受的响应类型 | Accept: text/html, application/json |
Content-Type | 请求体的数据类型(POST/PUT 时使用) | Content-Type: application/json |
Content-Length | 请求体的长度(单位:字节) | Content-Length: 123 |
Cookie | 客户端携带的 Cookie 数据,用于会话或身份识别 | Cookie: sessionid=abc123; theme=dark |
HTTP 响应头中包含什么?
响应头字段 | 作用说明 | 示例 |
---|---|---|
Content-Type | 响应体的数据类型,如 HTML、JSON、图片等 | Content-Type: application/json |
Content-Length | 响应体的字节长度 | Content-Length: 348 |
Set-Cookie | 设置 Cookie 给客户端,通常用于登录状态或跟踪 | Set-Cookie: sessionid=abc123; Path=/ |
Content-Encoding | 响应压缩方式 | Content-Encoding: gzip |
Get和Post有什么区别?
GET 和 POST 的主要区别在于参数传输方式和使用场景。
GET 把参数放在 URL 里,适合用于获取资源;POST 把参数放在请求体里,适合提交表单或数据。
GET 会被浏览器缓存,有长度限制,也容易被拦截,不适合传敏感信息;
而 POST 更安全,数据量大也没问题,更适合提交修改或新增操作。
此外,GET 通常是幂等的(无论操作执行多少次,结果都是一样的),POST 则可能带来副作用。
HTTP 长连接 vs. 短连接的区别是?
短链接就是客户端和服务端完成一次请求-响应后,TCP连接就立即关闭。下一次请求又得重新建立连接。HTTP1.0默认就是短连接,短链接效率低但省资源
长连接就是客户端和服务端完成一次请求-响应后,TCP连接不关闭,而是保持一段时间(直到超时或手动关闭),允许在这个连接上继续发送后续请求。HTTP1.1默认就是长连接,通过请求头connection:keep-alive实现。长连接效率高但占用资源
HTTP vs. HTTPS有什么区别?
HTTP和HTTPS的最大区别就是安全性。http是明文传输的,别人能在你和服务器之间偷看甚至篡改内容;而https在http基础上加入了SSL/TLS加密协议,实现加密传输,即使别人拦截到数据也看不懂,https还能验证服务端身份,防止钓鱼网站。https需要申请数字证书,默认使用443端口,http使用的端口是80。虽然https由于握手等过程会导致速度稍慢,但随着硬件性能提升这种速度上的差异可以忽略了,浏览器、搜索引擎更推荐使用https
HTTPS 的「秘钥交换 + 证书校验」全流程?
HTTPS的核心就是TLS加密,保证数据安全。流程其实就是浏览器和服务器先打个招呼,确认彼此支持啥加密算法。浏览器(客户端)会告诉服务器:“我这支持这些加密算法,咱们用哪个?”服务器看了看客户端支持的加密算法,就选了个两边都支持的算法,然后给你发过来它的身份证明----也就是数字证书,里面有服务器的公钥。
浏览器拿到证书会去验证它有没有过期、是不是给这个网站的,还有签名是不是权威机构签的,确保证书真没问题。验证完后浏览器就会随机生成一个对称加密的密钥,用服务器的公钥把他加密发过去,服务器收到后用自己的私钥解密,就拿到了这个密钥。这样两边就共享了一个私密钥匙(浏览器生成的那个对称加密密钥),接下来传输数据就是靠这个钥匙对称加密,速度快又安全。
总的来说就是,先确认身份(证书校验),再安全的交换"密码"(密钥交换),然后用这个密码加密通信。
WebSocket 简介 & 与 HTTP 的核心区别?
websocket简单来说就是一种全双工的通信协议,它建立在TCP之上,可以让服务端和客户端之间实现持续的、双向的通信连接。不像HTTP那种一次请求一次响应,websocket一旦建立连接双方就可以随时推送消息,比较适合即时聊天、实时推送、在线游戏这种对实时性要求高的场景。
区别:
①连接方式不一样:http是一次请求一次响应,客户端发一次请求,服务端返回一次数据就结束了;websocket是客户端发起一个请求握手之后,连接就保持着,后面双方可以随时发消息
②通信方式不一样:http是半双工,同一时刻只能一方发、另一方收;websocket是全双工,也就是客户端和服务端可以同时互相给对方发送消息
③性能方面:websocket更轻量,建立连接之后的数据不再有像http那样的头部冗余,而且不用频繁建立连接,能减少很多开销
④使用场景不同:http适合传统的网页加载、接口调用;websocket更适合高频率、实时交互的应用
从「敲下一个 URL」到「页面出现在屏幕」发生了什么?
当在浏览器中输入一个url后,首先浏览器会解析这个地址,看是哪个域名,然后走DNS解析流程去找域名对应的ip地址。接着就是建立连接,如果是http1.1就是TCP三次握手,如果是http3就是基于QUIC进行连接。如果是https还会再走一层TLS握手,打通加密路线。路线通了后,浏览器发出一个http请求,服务器收到请求后处理业务、准备资源、返回对应的HTML、CSS、JS等内容。浏览器边下载边渲染,构建DOM(把html内容解析成一个可以编程操作的树状结构,这个树表示有哪些元素)、CSSOM(浏览器对CSS的解析结果,表示这些元素怎么显示),执行JS(操控页面内容和行为),最终把页面加载出来。页面加载完毕后,如果短时间内没有新的请求,连接也会通过四次挥手正常关闭。
什么是重定向?重定向与请求转发的区别?
重定向就是服务器让请求的浏览器重新访问另一个地址
比如你访问 /login
,服务器说:“不行,你得先登录”,然后返回一个 302 或 301,让浏览器自动跳到 /loginPage
—— 这就叫重定向。
浏览器地址栏会变,用户能感知这个跳转。
请求转发就是服务器内部把请求,偷偷交给另一个资源处理,比如你访问 /a
,服务器内部判断你没登录,然后说:“这事我不处理,交给 /login
来处理”,但这个交接是在服务器内部完成的,浏览器完全不知道。
区别:
点 | 重定向 | 请求转发 |
---|---|---|
谁跳的 | 浏览器跳 | 服务器内部跳 |
地址栏 | 会变 | 不变 |
请求次数 | 两次 | 一次 |
数据能带过去吗 | 不能带请求体 | 可以共享请求数据(request) |
HTTP 是基于 TCP 还是 UDP?
HTTP/1.x系列和主流HTTP/2都是基于TCP的,而HTTP/3基于UDP,具体来说是基于UDP的QUIC协议
谈谈 HTTP 的缓存机制,服务器如何判断缓存是否过期?
http缓存就是浏览器或中间代理保存之前请求过的资源,下次访问时先用缓存,减少重复请求,加快速度,减轻服务器压力。
缓存有两个关键点:缓存的存活时间和是否更新
服务器通过响应头告诉客户端缓存策略,比如cache-control和expires指定缓存多久有效(这的有效指的是浏览器信任这个缓存没有更新,认为缓存还是有效的)。客户端如果在有效期内,直接用缓存,不去服务器。如果缓存时间过了,浏览器会带着缓存的标识(比如If-Modified-Since或If-None-Match)去问服务器这个资源有没有更新。
服务器收到后会比对资源最后修改时间或ETag(资源唯一标识),如果没有就返回304 Not Modified,告诉浏览器继续用缓存;如果变了,就返回新的资源给浏览器保存
简单来说,服务器靠时间戳或唯一标识ETag来判断缓存是否过期
注意:服务端会通过响应头告诉某些东西能不能缓存,缓存多久.....但真正保存缓存的是客户端
TCP解决了什么问题?
首先ip协议只是负责把数据从一台机器送到另一台机器,但是他不保证数据能不能送到、顺序对不对、有没有丢。所以光靠ip,就像打电话信号断了都没人管
tcp就是在这基础上做了增强,他能保证数据一定送到、保证顺序是对的,而且数据不会重复不会丢失。他还会在传的时候确定有没有收到,收到了就继续,没收到就重发。简单来说,tcp解决了ip不可靠的问题,让网络传输变得可靠、稳定。依赖的是tcp的三次握手和四次挥手机制。
TCP的头部格式?
tcp头有一些固定字段和可选字段组成。最基本的TCP头部是20字节+可选项,具体包含的有源端口和目的端口(用于说明谁发给谁)、序列号和确认号(保证数据顺序和可靠)、数据偏移(说明头部有多长)、标志位(比如说SYN\ACK\FIN来控制连接)等等。
TCP工作在那一层?
传输层,对于OSI七层模型来说工作在第4层的传输层,对于TCP/IP四层模型来说工作在传输层
上承会话层(7层)/应用层(4层)
下接网络层
TCP与UDP的区别?
最大区别是tcp可靠、udp不可靠;tcp会先通过三次握手建立连接、传数据时会确认并且数据丢失会重发,保证数据不丢不乱;而udp就是直接发,快,但是可能会丢数据,适合要求实时但不追求可靠的场景,比如语音、视频、直播这种。
TCP 和 UDP 的应用场景?
tcp适用于需要可靠、按序、完整数据传输的场景
如网页浏览、文件传输、数据库连接
udp适用于追求实时、低延迟、允许部分丢包的场景
如语音、视频通话、在线游戏
介绍少TCP的三次握手?
客户端调用 connect()
,发出一个带 序列号(SYN) 的包,此时进入阻塞状态。
服务端事先调用 listen()
和 accept()
,accept()
阻塞等待连接。
当服务端收到客户端的 序列号(SYN) 后,内核自动回复一个带 序列号+应答(SYN+ACK) 的包。
客户端收到这个 序列号+应答(SYN+ACK) 后,发送一个 应答ACK 确认,三次握手完成,connect()
返回。
当服务端收到客户端这个 应答ACK 时,连接正式建立,accept()
返回一个用于通信的新 socket。
介绍下四次挥手?
TCP 的四次挥手是为了优雅地断开连接。首先,客户端调用 close()
,发一个带 结束连接(FIN) 的包给服务端,表示“我这边发完了”。服务端收到后,回一个 ACK 表示“我知道了”,但这时它可能还有数据没发完。等它处理完后,也调用 close()
发一个 FIN 给客户端,表示“我也发完了”。客户端收到后再回一个 ACK,至此连接才真正断开。因为连接是双向的,所以需要双方都发一次 FIN,各自确认一次 ACK,所以一共是四次挥手。
除了标准的四次挥手(FIN/ACK)优雅关闭,TCP 还可以通过发送 RST 报文进行急迫中断(TCP 头部中 RST 标志位置 1,表示“重置连接“),以立即释放连接资源。
为什么挥手需要 TIME_WAIT?
TIME_WAIT 是 TCP 主动关闭方在连接关闭后进入的一个等待状态,主要有两个目的:一是确保主动关闭方最后发出的 ACK 包被对方收到,避免对方重发 FIN 导致连接异常;二是等待网络中残留的旧数据包自然消失,防止这些老包影响后续可能用相同 IP 和端口的新连接。这个等待时间一般是两倍最大报文寿命(MSL),保证连接彻底关闭和安全。
详解
作用一:
TCP 断开是四次挥手,主动关闭方最后要发一个 ACK 给被动关闭方,确认它的 FIN 包。
但是如果网络不稳定,最后那个 ACK 包可能没送到。被动关闭方没收到 ACK 会重发 FIN 包。如果主动关闭方已经关闭了连接,不再响应对方的 FIN,就会出现双方不一致,连接没完全关闭。
主动关闭方停留在TIME_WAIT状态的作用就是为了能继续接受被动关闭方重发的FIN,并重新发送ACK,确保对方确认连接关闭,保证双方都知道连接彻底断开
第二个作用:防止旧连接数据干扰新连接
TCP 连接是由4元组(源IP、源端口、目标IP、目标端口)唯一标识的。
如果没有 TIME_WAIT,网络中可能还有上一条连接的旧数据包延迟到达,新连接用同样的4元组,可能会误收老数据,导致错误。
TIME_WAIT 期间,旧数据包会被丢弃,确保下一次用同一4元组的新连接不会被“污染”
在 TIME_WAIT 状态收到新 SYN 会怎样?
TIME_WAIT 状态的一个作用就是:防止旧连接的“残留包”影响新连接。所以当一个连接处于 TIME_WAIT 时,操作系统会认为这个端口组合(四元组:源IP+端口、目的IP+端口)还在“冷却期”。所以,如果你这时候又用相同的四元组来发 SYN(比如短时间内重复 connect),操作系统一看:这个连接还在 TIME_WAIT,不接受!有些系统会直接丢掉这个 SYN;有些系统支持 “TCP 端口重用(如 SO_REUSEADDR / SO_REUSEPORT)”,会等 TIME_WAIT 快过了才允许你重连。
TIME_WAIT、CLOSE_WAIT 状态发生在哪一步?
-
CLOSE_WAIT
:被动关闭方(先收到 FIN 的那一方)收到 FIN 后,TCP 内核回了 ACK,但应用程序还没调用 close(),所以卡在这里等,进入了CLOSE_WAIT状态
。 -
TIME_WAIT
:主动关闭方,完成四次挥手最后一步后,进入 TIME_WAIT 等两倍 MSL,防止连接关闭不一致和旧包乱入。
TCP如何保证的可靠传输?
TCP 主要靠这几个机制保证可靠传输:
-
三次握手建立连接,确保双方都准备好了再传数据。
-
序号(Sequence Number)+ 确认应答(ACK),能标记每个包的顺序,也能确认对方有没有收到。
-
重传机制,包丢了没收到 ACK,会自动重发。
-
接收方有滑动窗口,发送方有拥塞控制,能控制流量,避免网络堵塞。
-
校验和,能检测传输过程中的数据损坏。
序号(Sequence Number)+ 确认应答(ACK):
-
每个 TCP 数据包都有一个序号(seq),比如:1001、1002...
-
收到方返回一个 ACK,说“我已经收到了你发的这个序号,下一段请发这个序号之后的数据”;
-
如果有数据没到,ACK 就不会变,发包方就知道这块数据还没收到。
这样就不会出现“顺序错了”或者“漏了数据还不知道”。
重传机制(超时重传 + 快速重传):
-
如果发送的数据长时间没收到 ACK,就触发超时重传。
-
或者接收方连续回了几个相同的 ACK(表示中间某块数据没到),就触发快速重传。
这样就算网络临时丢了包,TCP 也能自动把它补上。
滑动窗口 + 拥塞控制:
-
接收方告诉发送方“我这能一次收多少”(滑动窗口大小);
-
发送方按这个节奏发,比如窗口是 10 个包,那我就最多发 10 个包没收到 ACK 前不能继续发;
-
拥塞控制会动态调整这个窗口,比如网络不太通畅,就自动降速。
校验和:
-
发包时 TCP 把整段数据算一个校验和(就是一串数字);
-
接收方收到后也算一遍校验和,和原来的比对;
-
如果对不上,说明数据出问题了,直接丢掉不接收。
socket 通信的具体步骤是什么?
socket通信一般分为6个步骤:首先客户端和服务端都要通过socket()创建套接字,服务端用bind()绑定ip和端口,然后用listen()监听绑定的端口的连接请求;客户端调用connect()发起连接,服务端通过accept()接收连接,三次握手完成后双方就可以通过send/recv互相发送和接收数据;四次挥手后双方都用close关闭连接,释放资源。
服务端如何提速?
一是连接接入优化:在 listen()
函数中设置 backlog
参数,控制内核连接等待队列长度,减小高并发时丢连接的风险;同时,在 socket()
后用 setsockopt()
设置 SO_REUSEPORT
,允许多个 socket 绑定同一端口,实现多线程/多进程分担连接压力,提升接入能力。
二是引入高效 I/O 模型:用 epoll
(Linux)替代传统阻塞 I/O,支持大规模并发连接,避免线程阻塞,提高 I/O 处理效率。
三是引入并发结构:通过线程池复用工作线程,降低频繁创建/销毁线程的开销;进一步可以使用协程模型,单位资源下支持更高并发,提升吞吐量和响应速度。
发布者:admin,转转请注明出处:http://www.yc00.com/web/1754094239a5117601.html
评论列表(0条)