【UE项目迁移银河麒麟(Linux)局域网会话搜索失败排查】

📝 UE 项目迁移银河麒麟(Linux)局域网会话搜索失败排查笔记

一、 问题现象

· 背景:UE 项目从 Windows 迁移至银河麒麟(Kylin)系统,常规打包成功。

· 表现:

· 主机端调用 CreateSession 创建房间成功。

· 客户端调用 FindSession 搜索不到任何房间(返回结果为空,UI 列表不显示)。

· 但是,客户端使用 Open IP:Port 直接连接主机是可以成功进入的。

· Windows 系统下此流程完全正常。

二、 排查过程

1. 服务端监听验证(正常)

· 在主机端抓包/查看日志,确认 CreateSession 后底层网络驱动工作正常。

· 终端日志显示:IpNetDriver listening on port 7777。

· 使用 netstat / ss 命令验证,确认 7777 端口(UDP/TCP)已处于监听状态,绑定地址为 0.0.0.0。

2. 客户端报错定位(核心线索)

· 客户端运行游戏点击"搜索房间"后,终端输出关键报错:

LogTemp: Warning: Failed to send discovery broadcast SE_ENETUNREACH

· 同时伴随蓝图报错:Attempted to access index 0 from array 'Temp struct Variable' of length 0(因搜索结果为空导致)。

3. 环境确认(多网卡干扰)

· 执行 ip addr 查看客户端和主机端的网络环境。

· 发现系统存在多个网络接口:物理网卡 enp5s0(IP: 192.168.1.x),以及大量 Docker 虚拟网桥(docker0、br-56...)和虚拟网卡(veth...)。

· 判断:Linux 系统内核在发送全局广播(255.255.255.255)时,因多网卡存在导致路由表混乱,内核不知道从哪个网卡发出去,从而直接拒绝发包。

4. 网络连通性测试(证明物理链路畅通)

· 停止 Docker 服务(systemctl stop docker),重新搜索,问题依旧。

· 手动使用 nc 命令测试发定向子网广播:

echo "test" | nc -u -b 192.168.1.255 7777

· 在主机端 tcpdump 成功抓到这个包,证明物理网络链路、网段、交换机配置完全没问题。

· 踩坑提示:用 nc 给 UE 发送纯文本包会让 UE 底层的 FBitReader 解析崩溃(SetOverflowed),因为 UE 期望的是特定的二进制握手协议。这反证了 UE 原生广播无法发出,但链路通畅。

5. 锁定内核心结(抓包对比)

· 在客户端指定物理网卡抓包:sudo tcpdump -i enp5s0 -n udp port 7777。

· 结果:毫无反应。客户端执行 FindSession 时,系统底层根本没有把包发到物理网卡上(被内核吞了或路由到了虚拟网卡)。

三、 最终解决方案与原因剖析

🎯 解决方案(临时修复)

在主机端和客户端都执行以下路由命令(假设真实物理网卡名为 enp5s0):

```bash

sudo ip route add 255.255.255.255 dev enp5s0

```

执行完毕后,两端重新运行游戏,客户端成功搜到主机创建的会话!

🔍 为什么必须"两端都加"?

  1. 客户端(发包端):添加路由后,强制内核将发往 255.255.255.255 的全局广播包从物理网卡 enp5s0 扔出去,解决了 SE_ENETUNREACH 报错。

  2. 主机端(收包与回包端):主机收到探测包后,UE 引擎在回包时,底层逻辑依然会尝试使用带有全局广播地址的 Socket 或路由逻辑。如果主机端不加这条路由,它的响应包也会被多网卡路由表迷惑,丢进 docker0 或虚拟网桥的黑洞中。客户端收不到响应,UI 依然显示 0 个房间。

四、 后续优化建议(重要!)

1. 临时方案的重启失效问题

ip route add 命令是临时生效的,系统重启后会丢失。

· 建议:编写开机自启脚本,或者在网卡配置文件中添加静态路由,确保每次开机自动执行。

2. 正式发布项目的代码级根治(强烈推荐)

要求玩家或客户敲 Linux 命令是不现实的,必须在 UE C++ 代码层面绕过这个跨平台深坑。推荐以下三种方案:

· 方案 A(最推荐):绑定物理网卡

在创建 Socket 时,通过 FUdpSocketBuilder 的 .BoundToDevice(TEXT("enp5s0")) 强制绑定到真实物理网卡,不再让内核自己去猜。

· 方案 B:改用定向子网广播

放弃引擎默认的 255.255.255.255,在 C++ 代码中手动计算出当前网段的定向广播地址(如 192.168.1.255),并强制以此为目标发送。

· 方案 C:手写单播扫描(终极兜底)

完全绕开 FindSession 的广播机制。在 C++ 中写一个循环,从 192.168.1.1 遍历到 192.168.1.254,向每个 IP 的 7777 端口发送自定义探测包。主机端收到后回复信息,客户端将回包的主机加入 UI 列表,点击时走现有的 Open IP 逻辑。


核心工具:ip addr, ip route, tcpdump, nc, ss, strace, iptables

相关推荐
蒸鱼Yuzheng17 小时前
游戏内存碎片诊断:总量没超标,为什么仍然分配失败
unreal engine·性能分析·内存优化·分配器·内存碎片
wasee0013 天前
VR大空间复购率为什么低?内容更新与二次消费解决方案
vr
架构师伯子明5 天前
VR ATW原理
vr
BugPhysician5 天前
影之刃零首发UE崩溃排查:着色器缓存、虚拟内存与驱动版本
ue5·影之刃零·影之刃零报错·影之刃零进不去·ue崩溃·ue引擎崩溃·ue5引擎崩溃
架构师伯子明6 天前
VR视频渲染-重映射
vr
电子云与长程纠缠6 天前
UE5魂系游戏开发教程05
开发语言·学习·游戏·ui·ue5
fanfan_hongyun7 天前
UE5.1 蓝图调用C++方法
ue5
易知微EasyV数据可视化7 天前
UE5 中接入 GDAL:从vcpkg编译到插件打包
ue5
努力学习的小廉7 天前
UE5入门系列(一):环境搭建.md
ue5
fanfan_hongyun7 天前
【UE5.1 创建C++文件】
c++·ue5