Network.TestConnection

Switch to Manual
public static ConnectionTesterStatus TestConnection (bool forceTest= false);

Description

测试此机器的网络连接。

根据机器具有公共 IP 地址还是仅有私有地址,可执行两种测试。

公共 IP 地址测试主要用于作为服务器运行的情形,因为具有公共地址的客户端无需测试。为了 成功进行公共 IP 测试,必须启动一个服务器实例。测试服务器会尝试连接到本地服务器的 IP 和端口, 以显示该服务器可接受连接。否则,服务器端口很有可能被防火墙阻止。 服务器实例需处于运行状态,以便测试服务器能够建立连接。

另一个测试是检查 NAT 穿透能力。该测试对服务器和客户端均有效, 而且无需事先设置就可以进行测试。NAT 测试会有 4 种结果(请参阅 ConnectionTesterStatus):__Full Cone_、Address Restricted ConePort restrictedSymmetric

前两种提供完全 NAT 穿透支持,可连接到任何类型。端口限制类型无法连接到对称类型,也不能接收来自对称类型的连接。 对称类型是最糟糕的情况,无法连接到其他对称类型或端口限制类型。后两种被标记为 提供有限的 NAT 穿透支持。

此函数是异步函数,可能不会立即返回有效的结果, 因为测试需要一定时间才能完成(1-2 秒)。测试完成后,测试结果仅在下一次再次调用该函数时返回, 不会重复进行一次完整的网络测试。这使得能够安全地频繁轮询该函数。如果希望进行另一个测试, 如网络连接是否发生变化,传入的 forceTest 参数应为 true。

此函数返回一个 ConnectionTesterStatus 枚举。


using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour { string testStatus = "Testing network connection capabilities."; string testMessage = "Test in progress"; string shouldEnableNatMessage = ""; bool doneTesting = false; bool probingPublicIP = false; int serverPort = 9999; bool useNat = false; float timer = 0.0f;

ConnectionTesterStatus connectionTestResult = ConnectionTesterStatus.Undetermined;

void OnGUI() { GUILayout.Label("Current Status: " + testStatus); GUILayout.Label("Test result : " + testMessage); GUILayout.Label(shouldEnableNatMessage);

if (!doneTesting) TestConnection(); }

void TestConnection() { // Start/Poll the connection test, report the results in a label and // react to the results accordingly connectionTestResult = Network.TestConnection(); switch (connectionTestResult) { case ConnectionTesterStatus.Error: testMessage = "Problem determining NAT capabilities"; doneTesting = true; break;

case ConnectionTesterStatus.Undetermined: testMessage = "Undetermined NAT capabilities"; doneTesting = false; break;

case ConnectionTesterStatus.PublicIPIsConnectable: testMessage = "Directly connectable public IP address."; useNat = false; doneTesting = true; break;

// This case is a bit special as we now need to check if we can // circumvent the blocking by using NAT punchthrough case ConnectionTesterStatus.PublicIPPortBlocked: testMessage = "Non-connectable public IP address (port " + serverPort + " blocked), running a server is impossible."; useNat = false; // If no NAT punchthrough test has been performed on this public // IP, force a test if (!probingPublicIP) { connectionTestResult = Network.TestConnectionNAT(); probingPublicIP = true; testStatus = "Testing if blocked public IP can be circumvented"; timer = Time.time + 10; } // NAT punchthrough test was performed but we still get blocked else if (Time.time > timer) { probingPublicIP = false; // reset useNat = true; doneTesting = true; } break;

case ConnectionTesterStatus.PublicIPNoServerStarted: testMessage = "Public IP address but server not initialized, " + "it must be started to check server accessibility. Restart " + "connection test when ready."; break;

case ConnectionTesterStatus.LimitedNATPunchthroughPortRestricted: testMessage = "Limited NAT punchthrough capabilities. Cannot " + "connect to all types of NAT servers. Running a server " + "is ill advised as not everyone can connect."; useNat = true; doneTesting = true; break;

case ConnectionTesterStatus.LimitedNATPunchthroughSymmetric: testMessage = "Limited NAT punchthrough capabilities. Cannot " + "connect to all types of NAT servers. Running a server " + "is ill advised as not everyone can connect."; useNat = true; doneTesting = true; break;

case ConnectionTesterStatus.NATpunchthroughAddressRestrictedCone: case ConnectionTesterStatus.NATpunchthroughFullCone: testMessage = "NAT punchthrough capable. Can connect to all " + "servers and receive connections from all clients. Enabling " + "NAT punchthrough functionality."; useNat = true; doneTesting = true; break;

default: testMessage = "Error in test routine, got " + connectionTestResult; break; }

if (doneTesting) { if (useNat) shouldEnableNatMessage = "When starting a server the NAT " + "punchthrough feature should be enabled (useNat parameter)"; else shouldEnableNatMessage = "NAT punchthrough not needed"; testStatus = "Done testing"; } } }