背景

最近在玩群星,但是多人联机效果非常差,然后网上调研了一下发现可以用组网工具加速提升联机效果。

使用了一段时间之后发现有时候有效果有时候没有效果,所以研究了一下。

P2P实现的原理

Steam 数据报中继

https://partner.steamgames.com/doc/features/multiplayer/steamdatagramrelay?l=schinese

https://partner.steamgames.com/doc/api/ISteamNetworkingSockets#CreateListenSocketP2P

https://partner.steamgames.com/doc/api/ISteamNetworkingSockets#ConnectP2P

Steam的SDK中提供了可以直接用于P2P的接口,游戏只需要实现接口就实现P2P连接

Steam中的对等网络及共享IP 地址

https://help.steampowered.com/zh/faqs/view/1433-AD20-F11D-B71E

参考这篇文章介绍

使用中继进行对等连接

在建立直接连接时,视防火墙配置而定,NAT 遍历不一定总能成功。 如果失败,玩家就需要利用中继来和彼此交流。 每个玩家的防火墙都将接收来自中继的数据包。 (这篇文章很好地详细描述了这一流程。) 使用中继不需要和另一玩家分享您的 IP 地址,这是其好处之一。 通常,只有在无法建立直接连接的情况下,才会使用中继作为最后的方案,因为这项服务开销相对较大。 在这种情况下,即使不可能建立直接连接,双方也已经相互交换了 IP 地址,因此还是有可能发生 DoS 攻击。 如果一方或双方对等端拒绝分享 IP 地址,那么就不可能建立直接连接,NAT 遍历将会请求使用中继。 双方对等端必须都分享其 IP 地址,才能建立直接连接。

使用 Steam 网络 API 的游戏又如何呢?

如果游戏使用了最新的网络 API(ISteamNetworkingSockets 和 ISteamNetworkingMessages),那么流量将会通过 Steam 数据报中继(SDR)进行中继。这是 Valve 遍布全球的主干和中继网络,您可以决定何时允许某款应用分享您的 IP 地址。 在 “Steam”/“设置”/“游戏中”/“Steam 网络”中,有可以控制何时分享您 IP 地址的选项:

  • 从不
    永不和任何玩家分享您的 IP。 永远中继对等流量。
  • 始终
    始终允许应用和所有玩家分享您的 IP。 如果另一玩家也分享了其地址,则可能会建立直接连>接; 否则,进行中继。
  • 默认
    除非出现必须避免 Ping 时间过长的情况,否则此选项不会分享您的 IP 地址。
  • 仅限好友
    仅与您好友列表中的用户分享您的 IP。

也就是说如果相互之间允许IP分享,Steam会自动检测NAT,如果NAT能够打通那么就会直接建立P2P连接,否则会使用服务器进行中继。

检查Steam是否真的使用了P2P

在这一步,我们使用了N2N-V3进行了组网,使用NetLimiter检查进程所连接的IP和端口,P社的Stellaris进行验证

  1. 开启共享IP

    Steam -> 设置 -> 游戏中 -> Steam网络 -> 分享IP改为始终

    不太确定是不是实时生效,所以这一步改完了之后再把Steam退掉

  2. 组网后进入游戏,加入房间

​ 这一步需要注意,一定要先组网并验证相互之间已经连接成功,然后再开Steam然后进游戏

  1. 使用NetLimiter检查进程所连接的IP和端口

    10.144.6.xxx是N2N组网后的虚拟内网网段

​ 可以看到确实是走了内网,同时在同步存档的时候可以观察到Tap网卡上的大流量,不过是Steam建立了链接,推测是群星使用了Steam的SDK后由Steam转发了流量

优化思路

已经确定Steam的P2P可以走虚拟局域网,接下来就是优化N2N的效果

  1. 目前是打算阿里云的按量计费机器,2H2G,100Mbps带宽的流量,同时支持停机不计费和定时释放实例。

    会赠送20G的免费流量,按照6H小时开一把群星来算的话,6H*0.11/H+免费流量,费用很低,而且在用完之后可以停掉实例,后续使用的时候再开。

  1. 有时候就算N2N打通隧道,但是由于跨省结算的原因,可能会导致UDP不稳,此时可以考虑使用加上-S1强制走supernode中继来提升稳定性

最后

感谢朋友们的帮助和配合,来和我一起来优化联机的效果。