1.TCP/IP与OSI模型
1)TCP/IP模型
- 应用层:为程序提供网络服务。协议:HTTP,DNS与FTP等
- 传输层:提供端到端的通信服务,确保数据的可靠传输。协议:TCP与UDP
- 网络层:负责数据包的路由与转发。协议:IP
- 数据链路层:建立数据链路连接,传输以"帧"为单位的数据包。
- 物理层:负责比特流的物理传输。
2)OSI模型
将应用层细分为三层:
- 应用层:提供网络应用服务。
- 表示层:处理数据标识与编码。
- 会话层:负责两个通信实体间的建立,管理与终止会话。
2.三次握手与四次挥手
三次握手建立TCP连接,四次挥手断开TCP连接。
1)三次握手
问:三次握手的基本流程?
答:第一次握手:客户端向服务器发送SYN包(附带随机序列号),请求建立连接。
第二次握手:服务器收到后返回SYN-ACK包(确认序列(SYN序列号+1) 与 自身随机序列号)作为应答。
第三次握手:客户端收到后返回ACK包(随机序列号+1)。
问:为什么一定要三次握手?
答:第一次握手:服务器确认客户端可以发;第二次握手:客户端确认双方收发能力,服务器还不知道客户端能不能收到自己的包。
举例:如果客户端发送SYN连接请求,网络拥塞没有到达服务器,客户端超时没收到回复,重发SYN,但是旧的SYN到达服务器会建立连接,服务器空等浪费连接资源。
2)四次挥手
问:四次挥手的基本流程?
答:第一次挥手:客户端发FIN包给服务器,表示客户端不再发送数据。
第二次挥手:服务器收到后发送ACK包给客户端,表示已收到请求。(此时服务器可能还有数据没有发送,所以不能FIN与ACK一起发送,与三次握手不同,因此需要进行四次而不是三次)
第三次挥手:服务器完成数据传输后发送FIN包给客户端,表示服务器不再发送数据。
第四次挥手:客户端收到服务器的FIN包后,发送ACK包给服务器,表示收到请求。
3.TCP可靠传输的机制
1)序列号+确认应答(ACK) :发送方为每个传输字节分配唯一序列号 ,接收方收到后返回ACK,只有收到合法ACK,发送方才能确认接收方已经收到了。
2)超时重传:发送方未在规定时间收到ACK(超时),就重新发送。
3)滑动窗口:一次性批量发送多个包,收到连续ACK后窗口向前挪动。
4)流量控制:接收方在ACK中说明自己接收窗口的大小,发送方调整速率,防止接收方缓存区溢出
5)拥塞控制:
- 慢启动:刚开始慢发包,指数级增长窗口。
- 拥塞避免:到达阈值后线性增长。
- 快重传:连续收到三个重复ACK,立刻重传,不等超时。
- 快恢复:丢包后不从头开始,快速恢复传输速率。
6)数据校验和:发送方计算数据校验和,接收方验证,发现数据出错直接丢弃,要求重传。
4.TCP滑动窗口
1)概念:TCP通信中,发送方与接收方之间维护各自接收/发送缓冲区窗口。
2)流程:发送方根据接收方通知的窗口大小来确定发送数据的数量,一次性批量发送数据后等待接收方累计确认,确认后窗口滑动,再发送下一批数据,未确认的报文会重传。
3)优点:在保证可靠传输的前提下大幅提升传输效率,同时实现流量控制。
4)举例:不需要发一个等ACK再发下一个。例如:窗口大小=4,就一次性发4个(1,2,3,4),收到两个ACK(1,2),将窗口向前滑动,发(5,6)。
5.UDP与TCP/IP协议的区别
|--------|------------------------|--------------------------------|
| 区别 | UDP协议 | TCP/IP协议 |
| 连接特性 | 无需握手,直接打包发送数据 | 必须三次握手建立连接,传输完后四次挥手断开连接 |
| 可靠性 | 不保证数据可靠传输,可能导致丢包与乱序等情况 | 通过多种机制确保数据可靠传输 |
| 传输效率 | 效率高,速度快 | 效率低,速度慢 |
| 报文首部开销 | 8 字节(源端口+目的端口+校验和+长度) | 20 - 60字节(序列号+确认号+窗口大小+标志位等信息) |
| 传输方式 | 数据报 | 字节流 |
| 应用场景 | 实时性要求高(视频通话/直播) | 可靠性要求高(文件传输) |
6.实现UDP的可靠传输
1)基础可靠性机制
- 序列号机制:接收端按序列号排序并检测丢包。
cpp
struct PacketHeader {
uint32_t seq; // 序列号
uint32_t ack; // 已确认的最大序列号
uint16_t flags; // 标志位(如 ACK、SYN、FIN)
};
- 确认应答机制:接收方对收到的数据包发送ACK确认。
- 超时重传:为每个未确认的包启动重传定时器。
- 滑动窗口控制:发送窗口处理未确认的包,接收窗口处理乱序到达的包。
2)高级优化机制
- 快速重传
- 前向纠错
- 拥塞控制
- 路径MTU发现
3)协议实现步骤
- 连接管理:三次握手,四次挥手。
- 数据发送:
cpp
发送端:
1. 数据分片 → 打序列号 → 加入发送队列
2. 滑动窗口内包发送 → 启动定时器
3. 收到 ACK → 移动窗口 → 释放缓冲区
4. 超时/重复 ACK → 触发重传
接收端:
1. 检查序列号 → 丢弃重复包
2. 缓存乱序包 → 发送 SACK
3. 按序提交数据 → 更新 ACK
7.Http协议相关内容
1)基本概念
是基于 TCP/IP 的应用层协议,由请求-响应组成,采用客户端-服务器模型,用于客户端与服务端之间传输超文本(网页、图片、接口数据等)。
注:每次请求独立,服务器不会保留之前请求。
2)Http请求方式
- GET:从指定资源请求数据
- POST与PUT:将数据发送到服务器来创建/更新资源
- DELETE:删除指定资源
3)Http报文结构
1)请求报文 = 请求行(请求方法+URL+协议版本)+请求头(键值对)+请求体(POST/PUT提交的数据)
2)响应报文 = 响应行(状态码+状态描述+协议版本)+响应头+响应体(HTML,JSON等实际数据)
4)POST与GET区别
|-------|---------------|------------------|
| 区别 | GET | POST |
| 传输数据量 | 不大于2KB | 无限制 |
| 作用 | 从服务器获取数据 | 向服务器传送数据 |
| 幂等性 | 幂等,多次请求返回结果一致 | 非幂等,多次提交可能重复创建数据 |
| 参数位置 | 参数拼接在URL后面,可见 | 参数放在请求体中,不可见 |
5)Http长连接与短连接
(1)短连接:客户端与服务器的每一次请求-响应都会打开一个新的连接。
注:适用于低频请求,简单请求-响应交互与负载均匀的场景。
(2)长连接:建立一次连接,连续多个请求-响应,只有一方明确关闭或者空闲超时才会关闭。
注:适用于高频请求,需要快速响应与实时通信的场景。
8.粘包与分包
网络通讯中,粘包和分包是基于 TCP 协议的数据传输时常见的现象。
1)粘包:当发送的数据量小且发送频率高时,TCP协议为提升效率,会自动将小数据合并发送。而接收方无法将合并的数据分开,就导致本该独立的数据包"粘"在一起。
2)分包:当一次要发送数据量过大,由于TCP协议对每次传输的数据量有限制,数据会分成几部分发送,接收方每次只能接收到部分数据。
常见解决方案:
- 固定长度报文法:发送/接收方都会按固定的长度发送/接收。如果发送长度不足,就填充;如果发送长度超出,就拆分多次发送。
- 添加报文长度法:在每个报文前添加一个固定长度来表示报文长度。接收方先读头部长度信息,据此接收后面相应长度的数据,从而准确解析报文。
- 使用分隔符法:在不同报文之间添加特定分隔符,接收方通过查找分隔符区分不同报文,但要求报文内容不能出现相同的分隔符,否则会解析错误。
9.帧同步与状态同步
1.帧同步:同步的是玩家输入指令,所有端并行执行相同逻辑,服务端仅负责输入转发与校验。
2.帧同步流程:
- 每个逻辑帧周期内,客户端手机玩家指令,压缩上传服务器。
- 服务端收集所有玩家的当前帧输入,打上全局唯一帧号,生成全局输入帧广播给所有客户端。
- 客户端收到后才会执行该帧游戏逻辑。
优点:操作延迟低,宽带要求低,支持回放/观战(只需要保存输入序列)。
缺点:防作弊弱,对逻辑要求高(不确定性会导致多端分歧)。
优化方案:乐观帧同步+网络回滚:客户端先做执行逻辑,在未收到远端输入时预测,若预测错误则回滚对应帧快照(客户端),用远端传来的真实输入重放后续帧。
3.状态同步:同步的是游戏状态结果,服务端负责游戏逻辑计算,客户端表现层渲染。
4.状态同步流程:
- 客户端玩家按下指令,本地预表现,同时输入指令上传服务端。
- 服务端收到后做合法性校验,再在固定帧中执行完整游戏逻辑,得到全局游戏状态。
- 服务端将增量状态变化(发生变化的数据),广播给视野内的客户端。
- 客户端接收权威服务端权威状态
优点:防作弊强,设备帧数不影响逻辑一致性。
缺点:服务端成本高,操作有延迟,宽带要求高,回放/观战难实现。