用于检查本地网络环境并对 ping 进行估测的杂项网络实用工具。
相关文档:
ISteamNetworkingUtils 的成员函数通过全局访问器函数 SteamNetworkingUtils() 调用。
初始化与状态检查
InitRelayNetworkAccess
void InitRelayNetworkAccess();
如果您知道您将会使用中继网路(比如您预期会进行 P2P 连接),调用此函数以初始化中继网络。 如果您不调用此函数,初始化将会被推迟,直到您首次看到需要访问中继网络的功能,而这会推迟首次访问。
如果之前的尝试失败,您也可以调用此函数以强制进行重试。 执行任何要求访问中继网络的操作也将会触发一次重试,因此从不严格要求调用此函数,但如果预期会访问中继网络,那么在启动程序时调用可能会有帮助。 使用
GetRelayNetworkStatus 或侦听
SteamRelayNetworkStatus_t 调用,以了解初始化何时完成。 初始化一般在几秒内完成。
注意:托管于已知数据中心的专用服务器无需调用此函数,因为这些服务器不会做出路由决定。 然而,如果专用服务器将会使用 P2P 功能,那么它将会作为“客户端”,应该调用此函数。
GetRelayNetworkStatus
ESteamNetworkingAvailability GetRelayNetworkStatus( SteamRelayNetworkStatus_t *pDetails );
获取中继网络的当前状态。
SteamRelayNetworkStatus_t 同样是回调。 每当状态变更,或 ping 测量开始或结束时,它将会在用户端和游戏服务器接口触发。
返回 SteamRelayNetworkStatus_t::m_eAvail。 如果需要更多详情,可传入一个非 NULL 值。
Ping 地点函数
我们使用部署于全球的 Valve 中继的 ping 时间来生成一个“标记”,描述互联网主机的地点。 若有两个这样的标记,我们就可以估计两个主机之间的网络延迟,而不需发送任何数据包。 估计结果是通过基于 Valve 网络而找到的最佳线路而得出的。 如果您在使用 Valve 网络来承载流量,那么这正是您需要的 ping。 否则,ping 时间仍将是合理的估计。
这对于在对战匹配中选择可选的对等端来说及其有用!
标记还可以转换为字符串,因此可以传输。 我们有单独的库供您在自己的后端使用,以操控这些对象。 (见
steamdatagramrelay)
GetLocalPingLocation
float GetLocalPingLocation( SteamNetworkPingLocation_t &result );
返回当前主机的地点信息。 返回数据的大概存在时间,以秒计,如果无可用数据,则返回 -1。
初始化对中继网络的访问需要几秒种的时间。 如果在调用
InitializeRelayNetworkAccess 后立刻调用此函数,可能还没有可用数据。
它总是返回当前最新的信息,即便处于重新计算 ping 时间的过程中也是如此。
EstimatePingTimeBetweenTwoLocations
int EstimatePingTimeBetweenTwoLocations( const SteamNetworkPingLocation_t &location1, const SteamNetworkPingLocation_t &location2 );
估计两个随机地点之间的往返延迟,以毫秒计。 此为保守估计,基于通过中继网络的线路而得出。 对于最基本的中继连接而言,此 ping 时间将十分准确,因为它基于的是可能真正使用的路线。
如果使用了直接的 IP 线路(可能是通过 NAT 遍历),那么该线路会是不同的线路,且可能会有更佳的 ping 时间。 但也有可能是稍差一些的 ping 时间! 标准 IP 路由常常不能带来理想结果!
但即便如此,使用该方法获取的估计值也是 ping 时间的合理上限。 (此外它还有立即返回和不发送任何数据包的优点。)
在少数几种情况下我们可能无法估计路线。 如果是这样,会返回一个负值。 k_nSteamNetworkingPing_Failed 表明原因是网络障碍 (ping 失败等)。如果出于某种原因,我们当前无法回答问题,则返回 k_nSteamNetworkingPing_Unknown。
需要能够在后端/对战匹配服务器上进行此操作吗? 如果是,则“游戏协调程序”库正是您需要的。 参见
steamdatagramrelay,进一步了解如何获取游戏协调程序 SDK。
EstimatePingTimeFromLocalHost
int EstimatePingTimeFromLocalHost( const SteamNetworkPingLocation_t &remoteLocation );
和 EstimatePingTime 相同,但假定一个地点是本地主机。 此函数稍快,尤其是当需要循环计算多个此类函数以找到最快的那个时。
在极少的情况下,此函数返回的结果会稍不同于将 GetLocalPingLocation 与 EstimatePingTimeBetweenTwoLocations 结合的结果。 这是因为此函数会视使用的路线而采用稍微更复杂的一组信息。
ConvertPingLocationToString
void ConvertPingLocationToString( const SteamNetworkPingLocation_t &location, char *pszBuf, int cchBufSize );
将 ping 地点转化为适于网络传送的文本格式。 这种格式紧凑且便于阅读。 但它还会根据情况更改,因此请不要自行解析。 您的缓冲区必须为至少 k_cchMaxSteamNetworkingPingLocationString 字节。
ParsePingLocationString
bool ParsePingLocationString( const char *pszString, SteamNetworkPingLocation_t &result );
解析回 SteamNetworkPingLocation_t 字符串。 如果我们无法理解该字符串,则返回“false”。
Ping 测量状态函数
使用中继网络要求测量延迟时间。 除了在应用程序启动时调用
InitializeRelayNetworkAccess外(在您知道您将会需要访问中继网络以发送流量或只是估计 ping 时),延迟时间的采集过程将会自动发生。 这些函数允许对这一过程有更多一点的控制。
CheckPingDataUpToDate
bool CheckPingDataUpToDate( float flMaxAgeSeconds );
检查是否有近期的 ping 数据可用,如果 ping 数据太旧,则刷新。
请仅在您
确实需要强制数据立即刷新时才调用此函数。 (比如为了响应一个具体的用户输入而刷新此信息。) 请勿为了“以防万一”或在每次连接前调用此函数。那样会导致无谓地发送额外流量。 库会按需自动刷新该信息。
如果已有近期数据可用,则会返回“true”。
如果没有近期数据可用,则会返回“false”。 在这种情况下,ping 测量就算没有处于活跃状态,也已经启动。 (您无法重启已经在进行中的测量。)
IsPingMeasurementInProgress
bool IsPingMeasurementInProgress();
如果我们正在进行 ping 测量以更新我们的 ping 地点或选择最佳路径,则返回 true。 Ping 测量通常需要几秒钟,最长可能达到 10 秒。
Valve 网络拓扑函数
Valve 接入点(“POP”)列表及其 ping 时间。 如果您在使用我们的托管服务,或仅需要测量与包含我们的中继的云数据中心之间的延迟,此函数可能会有帮助。
GetPingToDataCenter
int GetPingToDataCenter( SteamNetworkingPOPID popID, SteamNetworkingPOPID *pViaRelayPoP );
提取从该主机到指定数据中心间的可用最佳中继路径的 ping 时间。
GetDirectPingToPOP
int GetDirectPingToPOP( SteamNetworkingPOPID popID );
获取接入点的中继的*直接* ping 时间。
GetPOPCount
int GetPOPCount();
获取配置中网络存在点的数量
GetPOPList
int GetPOPList( SteamNetworkingPOPID *list, int nListSz );
获取所有 POP ID 的列表。 返回填入您列表的条目的数量。
配置函数
控制网络选项。 见 ESteamNetworkingConfigValue,了解每个选项的描述。
SetConfigValue
bool SetConfigValue( ESteamNetworkingConfigValue eValue, ESteamNetworkingConfigScope eScopeType, intptr_t scopeObj,
ESteamNetworkingConfigDataType eDataType, const void *pArg );
设置一个配置值。
- eValue:正在设置哪个值?
- eScope:您正在将此设置应用于什么类型的对象?
- scopeArg:您想改变哪个对象? (若为全局范围则忽略)。 例如: 连接句柄、侦听套接字句柄、接口指针等。
- eDataType:在 pValue 缓冲区中的是什么类型的数据? 它必须与变量的类型完全匹配!
- pArg:要将其设为的值。
您可传递 NULL 来移除此范围中的非全局设置,令该对象的值使用全局默认值。 而在全局范围中,传递 NULL 将重设任何自定义值并将其恢复为系统默认值。
注意:当设置指针(如回调函数)时,请勿直接传递函数指针。 您的自变量应该为函数指针的指针。
char
const char *GetConfigValueInfo( ESteamNetworkingConfigValue eValue, ESteamNetworkingConfigDataType *pOutDataType, ESteamNetworkingConfigScope *pOutScope );
获取关于配置值的信息。 返回值的名称,如果值不存在,则返回 NULL。 如果不需要其他输出参数,则其他输出参数均可以为 NULL。
IterateGenericEditableConfigValues
ESteamNetworkingConfigValue IterateGenericEditableConfigValues( ESteamNetworkingConfigValue eCurrent, bool bEnumerateDevVars );
循环访问当前环境中可以使用通用 UI 显示或编辑的所有配置值的列表。 要获取第一个可循环访问的值,请传入 k_ESteamNetworkingConfig_Invalid。 返回 k_ESteamNetworkingConfig_Invalid,表示列表到此结束。
bEnumerateDevVars 参数可用于纳入“dev”变量。 建议仅在“调试”或“开发”模式下编辑这些变量;一般来说,它们不应在零售环境中显示,因为怀有恶意的本地用户可能会利用它作弊。
常见情况的快捷操作
以下函数是常见使用情况中的方便快捷操作。
bool SetGlobalConfigValueInt32( ESteamNetworkingConfigValue eValue, int32 val );
bool SetGlobalConfigValueFloat( ESteamNetworkingConfigValue eValue, float val );
bool SetGlobalConfigValueString( ESteamNetworkingConfigValue eValue, const char *val );
bool SetConnectionConfigValueInt32( HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, int32 val );
bool SetConnectionConfigValueFloat( HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, float val );
bool SetConnectionConfigValueString( HSteamNetConnection hConn, ESteamNetworkingConfigValue eValue, const char *val );
杂项函数
AllocateMessage
SteamNetworkingMessage_t *AllocateMessage( int cbAllocateBuffer )
分配并初始化消息对象。 调用此函数的通常原因是将其传递至
ISteamNetworkingSockets::SendMessages。 返回的对象中所有相关字段都会清零。
您还可以申请此系统分配空间以容纳有效负载本身。 如果 cbAllocateBuffer 为非零的值,系统将分配内存以容纳至少 cbAllocateBuffer 字节的有效负载。 m_pData 将会指向被分配的缓冲区,m_cbSize 将会设为其大小,m_pfnFreeData 将会设为合适的函数以清空缓冲区。
如果 cbAllocateBuffer=0,则没有分配缓冲区。 m_pData 将为 NULL,m_cbSize 将为零,m_pfnFreeData 将为 NULL。 您将需要为每一个都进行设置。
GetLocalTimestamp
SteamNetworkingMicroseconds GetLocalTimestamp();
一个通用型高分辨率本地记时器,带有以下属性:
- 保证单调性。
- 初始值将至少为 24*3600*30*1e6,也就是总长为 30 天的微秒数。 这样一来,为 0 的时间戳值将总是为至少“30 天以前”。 此外,不会返回负数。
- 从实际来看,无需担忧环绕/溢出。
SteamNetworkingMessage_t::m_usecTimeReceived 包含了来自同一记时器的时间戳。
如果您在调试程序下运行并停止该流程,时钟可能不会前进两个调用之间的完整自然时钟时间。 如果没有阻止该流程进行正常操作,时间戳的值将会跟随自然时钟时间,即便您没有频繁地调用该函数也是如此。
该值仅仅对该流程的本次运行有意义。 请勿将其与来自另一台计算机的值或同一流程的其他运行相比较。
SetDebugOutputFunction
oid SetDebugOutputFunction( ESteamNetworkingSocketsDebugOutputType eDetailLevel, FSteamNetworkingSocketsDebugOutput pfnFunc );
设置一个函数以接收便于调试的网络信息。
这可能在开发时极为有用,在与精通技术的终端用户进行故障排除时也可能很有帮助。 如果您有主控台日志或客户可以检查的其他日志,这些日志消息对于排除网络故障常常很有帮助。(尤其是任何警告/错误消息。)
细节级别表示在什么消息上调用回调。 数字越低表示越重要,而您传递的值是您希望最后一个(数字最高)收到回调的。 但如果在调试时,则应该使用
k_ESteamNetworkingSocketsDebugOutputType_Msg 或 k_ESteamNetworkingSocketsDebugOutputType_Warning。 为求最佳性能,请不要申请一个高细节级别然后又在回调时过滤掉消息。 相反地,请调用此函数以调整想要的细节级别。
此值控制大多数消息的细节级别。 您可以通过调整配置值 k_ESteamNetworkingConfig_LogLevel_Xxxxx 来控制各种子系统(可能仅适用于某些连接)的细节级别。
重要:此函数可以从一个服务线程,或者在我们拥有互斥体等情况下调用。
您的回调函数必须是线程安全且快速的!请勿在该句柄内进行任何其他 Steamworks 调用。
Fake IP
“FakeIP”系统可用于与假设使用 IPv4 地址识别对等段的代码进行交互。 请参阅
ISteamNetworkingSockets,了解更多信息。
IsFakeIPv4
bool IsFakeIPv4( uint32 nIPv4 );
如果 IPv4 地址可能被用作“假”地址,返回 true。 此函数速度很快;它只是对 IP 做一些逻辑测试,不需要做任何查找操作。
GetRealIdentityForFakeIP
EResult GetRealIdentityForFakeIP( const SteamNetworkingIPAddr &fakeIP, SteamNetworkingIdentity *pOutRealIdentity );
获取与给定 FakeIP 关联的真实身份。
失败时,返回:
- k_EResultInvalidParam:该 IP 不是 FakeIP。
- k_EResultNoMatch:我们无法识别该 FakeIP,也不知道相应的身份。
有效连接中使用的 FakeIP 或分配给本地身份的 FakeIP 将始终有效。 最近被破坏的连接的 FakeIP 将在一段时间内继续返回结果,但不会一直返回结果。 在某个时间点,我们将忘记 FakeIP 以节省空间。 可以比较肯定地假设,您可以在连接被破坏后很快读回连接的真实身份。 但请勿无限期地等待。