Unity 3D 笔记(十二)Unity/C# Socket 网络笔记1

本篇核心知识点:Socket 定义、IP 与端口作用、长连接 / 短连接区分、进程 / 线程 / 协程区别、高并发场景、TCP 三次握手 / 四次挥手、服务器日志 Log4Net、Socket Select 多路复用、客户端连接管理、心跳包机制、时间戳计算、服务端完整运行架构、try-catch 异常捕获

一、Socket 基础概念

1 概念

Socket 是一套通信端点接口,用于两个程序(客户端 / 服务)建立数据传输通道,由 IP 地址 + 端口唯一标识一条通信链路,是网络游戏客户端与服务通信底层核心。

2 特性 / 规则

  1. IP 作用:定位网络中一台物理设备(电脑 / 手机服务器);

  2. 端口作用:区分同一设备上多个不同程序服务,一台机器多个程序占用不同端口;

  3. 知名固定端口:80 网页、8080 后台服务、22 远程、3389 远程桌面;

  4. 游戏项目 95% 采用 Socket 长连接架构,网页 HTTP 属于短连接。

3 语法 & 代码片段

复制代码
// 引入网络命名空间
using System.Net.Sockets;
using System.Net;
// 创建服务端监听Socket
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 绑定本机IP与端口
// private string ipStr = "127.0.0.1"; // 自定义ip
// private int port = 8011; // 自定义端口
// IPAddress ip = IPAddress.Parse(ipStr); // ip字符串转ip地址
// IPEndPoint endPoint = new IPEndPoint(ip, port);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 8899);
listenSocket.Bind(endPoint);
// 开启监听 数量上限1000
listen.Listen(1000);

4 相关知识点对比

长连接 Socket VS HTTP 短连接

Socket 长连接:连接建立后持续保持,服务端可主动推送消息,网游必备;

HTTP 短连接:每次刷新 / 请求新建链路,服务端无法主动发消息,网页、后台管理系统使用。

5 模块拓展

网游场景区分:MMORPG 多人主城高并发强需求 Socket;回合 / 射击房间类数据量小,网络压力更低。

二、进程、线程、协程三者区分

1 概念

  1. 进程:操作系统资源分配最小单元,独立软件程序(微信、VS、游戏客户端),拥有独立内存;

  2. 线程:CPU 调度最小执行单元,属于进程内部执行分支,同一进程多线程可并发执行;

  3. 协程:线程内分段执行逻辑,非独立线程,Unity 主线专用,服务端较少使用。

2 特性 / 规则

  1. 资源仅分配给进程,线程共享所属进程全部内存资源;

  2. 同进程线程可直接交互,跨进程通信成本极高;

  3. 并发支持:线程可实现高并发处理大量客户端连接;

  4. 调度层级:进程 = 资源载体,线程 = 执行调度载体。

3 语法 & 代码片段

服务端多线程简易示意片段

复制代码
// 新开子线程处理Socket循环
Thread serverThread = new Thread(ServerMainLoop);
serverThread.IsBackground = true;
serverThread.Start();

4 相关知识点对比

进程 VS 线程

进程:独立内存、独立资源,跨进程通信开销巨大;

线程:共享进程内存,并发效率高,服务端处理连接标准方案。

5 模块拓展

高并发参考:12306 铁路系统海量请求,依靠多线程 + 分布式架构承载流量。

三、网络基础:延迟与带宽

1 概念

  1. 延迟:客户端发送消息→服务接收→返回完整耗时;

  2. 带宽:单位时间可传输数据总量,海量玩家同屏会占用大量带宽资源。

2 特性 / 规则

  1. 传奇类多人同屏主城延迟、带宽压力极高;

  2. 王者 / LOL 房间制仅 10 人交互,网络压力小;

  3. 隧道、切后台会造成临时网络断开,区分内存崩溃与心跳超时掉线。

3 相关知识点对比

高延迟场景 VS 低延迟场景

多人 MMO 主城:大量玩家同步位置、技能,延迟敏感;

房间竞技:单局人数固定,同步数据少,延迟容忍度更高。

4 模块拓展

服务器分区逻辑:单服承载千人以内,拆分多区分割并发压力。

四、Log4Net 服务端日志组件

1 概念

第三方日志记录库,服务端运行所有报错、连接、操作记录持久写入本地文本,线上出现 bug 可回溯日志定位问题。

2 特性 / 规则

  1. VS 工具->NuGet 包管理器->管理解决方案 浏览在线安装,优先选择稳定旧版本,新版存在未知 Bug;

  2. 配置文件设置日志输出格式、存储目录;

  3. 程序运行自动生成日志文件夹,日志精确到时分秒;

  4. 项目输出目录设置:配置文件复制到输出目录(如果较新则复制)。

3 语法 & 代码片段

复制代码
// 日志打印
log.Info("服务器启动监听成功");
log.Error("客户端连接异常:" + ex.Message);

4 相关知识点对比

原生 Console 打印 VS Log4Net 持久日志

Console:仅控制台临时输出,程序关闭全部丢失;

Log4Net:持久本地文件,线上运维排查 bug 必备。

5 模块拓展

日志分级:Info 正常流程、Error 异常崩溃、Warn 警告操作。

五、Socket 多路复用 Select 机制

1 概念

Select 函数一次性监听全部 Socket 集合,自动筛选存在可读数据的套接字,避免无意义循环空跑,大幅降低 CPU 占用,服务端标准高效 IO 处理方案。

2 特性 / 规则

  1. 传入三类集合:可读列表、可写列表、异常列表,仅处理可读连接;

  2. 超时单位微秒,设置极小值保证循环响应速度;

  3. 筛选后仅分两类处理:新客户端连接请求已有客户端收发数据

3 语法 & 代码片段

复制代码
List<Socket> readList = new List<Socket>();
// 填充全部监听+客户端Socket
readList.Add(listenSocket);
foreach(var client in clientDict.Values)
    read.Add(client.clientSocket);
// 多路复用筛选可读Socket
Socket.Select(readList, null, null, 1000);

4 相关知识点对比

死循环轮询所有 Socket VS Select 多路复用

无脑循环:CPU 持续高占用,大量空循环无效判断;

Select:仅处理有数据连接,空闲时挂起等待,性能大幅优化。

5 模块拓展

万级连接服务端全部采用 IO 多路复用架构。

六、客户端连接管理架构

1 概念

使用 Dictionary 字典存储全部客户端连接信息,Key=Socket、Value = 自定义客户端类,统一管理连接、断开、心跳检测。

2 特性 / 规则

  1. 自定义 Client 类:存储客户端 Socket、最后通信时间戳;

  2. 字典全局缓存所有在线玩家,快速遍历查找;

  3. 逆序遍历 Socket 列表,优先处理已有客户端数据,最后处理新连接请求。

3 语法 & 代码片段

复制代码
// 存储全部在线客户端
Dictionary<Socket, ClientInfo> clientDict = new Dictionary<Socket, ClientInfo>();
// 客户端信息实体
public class ClientInfo{
    public Socket clientSocket;
    public long lastRecvTime; // 最后收发时间戳
}

4 相关知识点对比

List 存储连接 VS Dictionary 存储连接

List:查找指定客户端需要循环遍历,效率低;

Dictionary:通过 Socket 键直接取值,查找 O (1) 效率。

5 模块拓展

玩家下线、踢人、批量离线操作基于字典遍历实现。

七、时间戳计算(UTC 标准)

1 概念

以 1970-01-01 00:00 UTC 为起点计算总毫秒数,不受电脑本地修改时间影响,服务端统一计时、活动倒计时、心跳判断标准方案。

2 特性 / 规则

  1. 本地 DateTime.Now 可人为修改,时间戳不受系统时间改动干扰;

  2. 长整型存储毫秒时间戳,用于心跳超时、活动倒计时差值计算。

3 语法 & 代码片段

复制代码
// 获取UTC标准时间戳
TimeSpan timeSpan = DateTime.UtcNow - new DateTime(1970,1,1,0,0,0,0);
long time = Convert.ToInt64(timeSpan.TotalSeconds);

4 相关知识点对比

本地 DateTime VS UTC 时间戳

DateTime.Now:用户可手动修改电脑时间,逻辑会错乱;

UTC 时间戳:全球统一标准,服务端计时、校验唯一标准。

5 模块拓展

活动倒计时、离线时长、登录间隔全部使用时间戳差值运算。

八、try-catch 异常捕获

1 概念

捕获代码运行异常,防止单个客户端报错导致整个服务器进程闪退,保证服务 7*24 小时稳定运行。

2 特性 / 规则

  1. 所有 Socket 读写、连接逻辑包裹 try-catch;

  2. 捕获异常后打印 Error 日志,继续循环接收新连接;

  3. 客户端异常断开、数据解析报错不会影响整体服务。

3 语法 & 代码片段

复制代码
try{
    Socket newClient = listenSocket.Accept();
}
catch(Exception ex){
    log.Error("接收客户端连接异常:" + ex.ToString());
}

4 相关知识点对比

无捕获直接运行 VS try-catch 捕获

无捕获:任意客户端异常直接导致服务程序崩溃;

捕获:单连接错误隔离,服务持续运行。

5 模块拓展

数据解析、数据库操作、文件读写全部加异常捕获。

九、心跳包超时检测机制

1 概念

客户端定时向服务发送空心跳数据包,服务记录最后接收时间;超过指定时长未收到心跳则判定掉线,主动关闭 Socket 释放资源。

2 特性 / 规则

  1. 基础心跳间隔 30 秒,预留容错倍数(2~3 倍)防止临时断网误踢;

  2. 手机切后台、隧道弱网不会直接踢下线,预留缓冲窗口;

  3. 遍历全部客户端字典,对比当前时间戳与最后通信时间戳。

3 语法 & 代码片段

复制代码
long nowTs = GetUtcTimeStamp();
List<ClientSocket>m_TempList = new List<ClientSocket>();
long heartLimit = 30; // 容错30s
​
foreach(ClientSocket clientSocket in clientDict.Value){
    if(nowTs - clientSocket.lastRecvTime > heartLimit * 4){
        m_TempList.Add(clientSocket); // 超时断开
    }
}
// 对心跳包超时的客户端进行统一处理
foreach(ClientSocket client in m_TempList){
    CloseClient(client);
}
m_TempList.Clear();

4 相关知识点对比

心跳踢下线 VS 程序内存崩溃掉线

心跳:网络弱、切后台、断网超时正常处理;

内存崩溃:系统直接销毁进程,无断开逻辑。

5 模块拓展

游戏切后台、锁屏、飞行模式全部依靠心跳机制处理离线逻辑。

十、服务端完整生命周期架构

1 概念

服务标准执行循环:启动监听 Socket→多路复用筛选可读连接→分新连接 / 已有客户端处理→心跳超时清理→循环往复。

2 特性 / 规则

  1. 启动阶段:绑定端口、开启监听、初始化日志、创建客户端字典;

  2. 循环阶段:Select 筛选 Socket、优先处理玩家数据、再处理新连接;

  3. 收尾阶段:心跳遍历清理超时离线客户端;

  4. 全程子线程运行,主线程控制台可打印状态。

3 语法 & 代码片段

复制代码
void ServerMainLoop(){
    InitServer(); // 初始化监听、日志
    while(true){
        List<Socket> readList = GetAllSocket();
        Socket.Select(readList,null,null,1000);
        DealAllReadSocket(readList); // 处理连接与数据
        CheckHeartTimeout(); // 心跳清理
    }
}

4 相关知识点对比

线性单次执行 VS 死循环服务架构

单次执行:处理一次直接退出,无法持续接收玩家;

永久循环:持续监听在线玩家,游戏服务标准架构。

5 模块拓展

拓展功能:消息序列化、数据库读写、玩家数据存档、协议分发。

综合拓展

1 服务端开发规范:全部 IO 操作加 try-catch、统一 UTC 时间戳计时、多路复用替代无脑循环、日志分层记录,禁止 Console 临时输出。

2 高频 Bug 排查清单

连接大量占用 CPU:未使用 Select 多路复用;

玩家无故掉线:心跳超时时间设置过短无容错;

日志无输出:Log4Net 配置文件未复制到输出目录;

服务无法接收连接:端口被占用、IP 绑定错误。

3 面试核心考点

Socket 长连接 / 短连接区别、Select 多路复用原理、心跳包作用、UTC 时间戳优势、进程线程协程区分、Log4Net 日志使用、服务主循环架构。

4 进阶拓展学习方向

Protobuf 二进制协议、MySQL 数据库玩家存档、分布式多服架构、断线重连、消息分发器、异步 IO 模型。

相关推荐
2401_891957311 小时前
简单了解传输层协议UDP
网络·网络协议·udp
AvatarAI_Walker1 小时前
2026年7月安徽本地健康IP孵化行业观察:不同需求下的服务方向梳理
大数据·网络·tcp/ip·搜索引擎·精选
一棵星1 小时前
WebSocket 长连接不稳?一次完整的排查与修复之旅
网络·websocket·网络协议
发量惊人的中年网工1 小时前
AI服务器托管怎么选机房?GPU集群对机柜、电力和网络的硬要求
服务器·网络·人工智能
EIP低代码平台2 小时前
EIP低代码平台 - 系统日志
低代码·c#·权限·工作流·netcore
玖玥拾2 小时前
Unity 3D 笔记(十五)Unity/C# Socket 网络笔记4
服务器·网络·unity·c#
JackieDYH2 小时前
WebSocket-不同平台封装-Hooks和使用案例
网络·websocket·网络协议
EIP低代码平台10 小时前
EIP 低代码平台 - 角色维护
低代码·c#·权限·工作流·netcore
andxe13 小时前
安科士 AndXe 技术博客:400G QSFP112 SR4 光模块|AI 算力与超算短距互联最优方案
网络·人工智能·光模块·光通信