한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

游戏卡顿白皮书 › 只有部分人遇到的问题

固定 UDP 端口冲突 Two clients bound to the same local UDP port

原因 ID pt-port-collision · 主责 研发团队·客户端开发 · 配合 研发团队·服务器开发

在含图示和实验的完整版中打开此卡片 →

客户端被做成使用固定的本地端口时,同一台电脑上的第二个客户端要么用不了这个端口,要么和第一个客户端分着收包。

起因 两个客户端要打开同一个本地 UDP 端口(用重用选项强行共用) → 结果 OS 只把收到的包交给其中一个 socket,或不保证由哪一个接收。路由器和服务器也把两个客户端看成同一个地址 → 画面表现 一边收不到世界数据包,看不到 NPC 和其他玩家,或者掉线

症状
隐身/幽灵实体, 掉线, 连不上/无限加载
因素
丢包
谁会遇到
双开时只有一个客户端
何时出现
刚登录/维护结束后, 一直
负责方
主责 研发团队·客户端开发 · 配合 研发团队·服务器开发
研发团队要做的事
客户端:本地端口由 OS 自动选择(bind 0 号端口)。服务器:用每个连接签发的会话令牌区分连接。
监控图上
仅部分偏高 · 各客户端收到的包数
查看位置
在玩家电脑上开着两个客户端,在命令提示符中用 netstat -ano -p udp 查看每个游戏进程(PID)打开的本地 UDP 端口。在服务器侧确认两个会话是否来自同一公网 IP、同一端口
确认依据
两个游戏进程绑定在同一个本地端口上,或在服务器上两个会话显示为同一 IP、端口。只开一个就正常
排除依据
两个客户端用的是不同的本地端口,一边仍然异常,看“按 IP/设备区分会话的 bug”或“多开限制”
确认手段
需在玩家侧环境确认

出处

  1. Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE Microsoft
    用 SO_REUSEADDR 对同一端口第二次 bind 会抢走端口,无法确定哪个 socket 收包
  2. bind function (winsock.h) Microsoft
    把端口设为 0 来 bind,会从动态端口范围(49152~65535)中分配一个唯一端口
  3. netstat Microsoft
    -a 显示 TCP、UDP 端口,-n 显示数字地址,-o 显示进程 ID(PID),-p udp 只显示 UDP

相关原因

同一层:只有部分人遇到的问题

其他层中同样导致“隐身/幽灵实体”的原因

查看含图示和实验的原卡片