游戏卡顿白皮书 › L2 客户端操作系统与设备
接收缓冲区溢出 Socket receive buffer overflow
原因 ID co-rcvbuf · 主责 研发团队·客户端开发
在含图示和实验的完整版中打开此卡片 →
游戏太忙,从 socket(操作系统提供的网络收发接口)里取数据包取得晚,操作系统的缓冲区就会溢出。
起因 帧处理积压,游戏读 socket 读得晚 → 结果 操作系统接收缓冲区填满后,UDP 直接丢弃,TCP 缩小接收窗口让发送方停止发送 → 画面表现 瞬移(UDP)或快进(TCP)
- 症状
- 瞬移, 快进
- 因素
- 丢包, 停顿
- 谁会遇到
- 只有我
- 何时出现
- 人多的时候
- 负责方
- 主责 研发团队·客户端开发
- 研发团队要做的事
- 专用接收线程,调整缓冲区大小(SO_RCVBUF)。
- 数值参考
- 默认接收缓冲区视操作系统和设置为几十到几百 KB。人多的地方,更新量有时可达每秒几百 KB。
- 监控图上
- 随人数/负载上升 · UDP 接收缓冲区丢弃数、帧耗时
- 查看位置
- 把 Windows 性能监视器的 Microsoft Winsock BSP\Dropped Datagrams(因 socket 接收缓冲区不足而丢弃的 UDP 数)、UDPv4\Datagrams Received Errors 与帧耗时一起记录,游戏侧统计收到的数据包序号中的空缺
- 确认依据
- 人多的地方或长帧之后 Dropped Datagrams 增加,同一时刻游戏的序号出现空缺。同一时刻线路侧没有丢包
- 排除依据
- Dropped Datagrams 不变、只有序号缺失,是路径上的丢包
- 确认手段
- 需在玩家侧环境确认
出处
- socket(7) — Linux manual page Linux man-pages
SO_RCVBUF 是 socket 接收缓冲区的最大大小,默认值由 rmem_default、最大值由 rmem_max 决定(Android 用的也是 Linux 内核) - SOL_SOCKET Socket Options (Winsock2.h) Microsoft
Windows SO_RCVBUF:每个 socket 为接收预留的缓冲区空间 - RFC 9293: Transmission Control Protocol (TCP) IETF
TCP 窗口字段是接收方还能接收的字节数;为 0 时,发送方只发零窗口探测并等待 - Low Latency Workloads Management and Operations Microsoft
Microsoft Winsock BSP 计数器集的 Dropped Datagrams、Dropped Datagrams/sec:UDP 到达速度超过应用处理速度,或接收 socket 缓冲区不足而丢弃的数量 - Network-Related Performance Counters Microsoft
UDPv4、UDPv6:Datagrams Received Errors,Microsoft Winsock BSP:Dropped Datagrams 计数器
相关原因
同一层:L2 客户端操作系统与设备
其他层中同样导致“瞬移”的原因
查看含图示和实验的原卡片