Source SDK 2013服务器发现机制:UDP广播到局域网服务器列表的完整链路
【免费下载链接】source-sdk-2013The 2013 edition of the Source SDK项目地址: https://gitcode.com/GitHub_Trending/so/source-sdk-2013
你在家跑了一个游戏服务器,想让同一WiFi下的朋友不用输IP就能在服务器列表里看到它,干这件事的就是 Source SDK 2013 的服务器发现机制。核心就是几包UDP广播,全程不需要三次握手。
服务器是怎么被局域网发现的
拆成三块看:服务端广播、客户端监听、消息编码。每块都不大,串起来才是一条完整链路。从哪块入手?先听服务端"喊话"。
服务端:用SendConnectionless广播自己的信息
一句话结论:服务器不需要任何连接状态,把自身信息打包进一个UDP包、往子网里发出去就行。入口在 src/public/inetwork.h 的INetwork::SendConnectionless:
virtual void SendConnectionless(netsrc_t sock, netadr_t &adr, unsigned char * data, int length) = 0;adr传广播地址即可,length是载荷实际字节数。Source 引擎默认游戏端口是 27015,记得把端口写进包里。
客户端:监听广播包并校验challenge
监听侧只有一个接口:实现IConnectionlessPacketHandler,再用INetwork::ProcessSocket注册,网络层就会把所有无连接包递给你。签名很简单:
virtual bool ProcessConnectionlessPacket(netpacket_t *packet) = 0;那客户端怎么区分真实服务器和伪造广播?靠challenge应答——无连接协议带一个质询字段,INetChannel::SetChallengeNr就是存它的地方。先校验、再入列表,顺序别反。
消息编码:位缓冲加类型标签
包内容不需要固定格式。INetMessage用bf_read/bf_write位缓冲读写,类型号由GetType给出(注释里举的例子就是svc_serverinfo这个标签):
virtual bool ReadFromBuffer(bf_read &buffer) = 0; virtual bool WriteToBuffer(bf_write &buffer) = 0; virtual bool Process(void) = 0;说白了,就是写的一侧和读的一侧,字节序由HostToNetShort/NetToHostShort统一处理,不用自己操心大小端。
从零到跑通的最短路径
- 客户端实现
IConnectionlessPacketHandler并用ProcessSocket注册——产出:能收到并解析广播包。 - 服务器每帧检查定时器,到点就用
SendConnectionless发服务器信息(地图名、人数、端口)——产出:局域网里出现周期性广播。 - 客户端用
ReadFromBuffer解析、按地址去重缓存、刷新服务器列表——产出:UI 里能看到服务器。 - 点连接后建立
INetChannel正式通道,走SVC_ServerInfo握手完成签入——产出:玩家进游戏。
避坑:广播频率与包大小
- 广播按 10~30 秒一次刷新,别每帧发:UDP 是无连接的——坏包直接没,不可重传,高频广播只会把局域网交换机刷爆;跟界面刷新周期对齐就够了。
- 包体越小越好:载荷超过可路由上限时引擎会切分包(
SetMaxRoutablePayloadSize控制这个阈值),切包在低端设备上极易丢;只放地图名、人数、端口这类必要字段。 - challenge 字段一定要校验:不校验的话,伪造广播能让客户端列出一台根本不存在的服务器。
- 广播不跨网段:UDP广播只覆盖本地网段,服务器在NAT后面就别指望它了,改走Steam服务器列表——
MM_Heartbeat消息干的就是这个。
资源索引
机制讲完,代码细节看这四个文件:网络接口 src/public/inetwork.h、无连接包处理 src/public/inetmsghandler.h、消息编码 src/public/inetmessage.h、频道与challenge src/public/inetchannel.h。
【免费下载链接】source-sdk-2013The 2013 edition of the Source SDK项目地址: https://gitcode.com/GitHub_Trending/so/source-sdk-2013
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考