测试此机器的网络连接。
根据机器具有公共 IP 地址还是仅有私有地址,可执行两种测试。
公共 IP 地址测试主要用于作为服务器运行的情形,因为具有公共地址的客户端无需测试。为了
成功进行公共 IP 测试,必须启动一个服务器实例。测试服务器会尝试连接到本地服务器的 IP 和端口,
以显示该服务器可接受连接。否则,服务器端口很有可能被防火墙阻止。
服务器实例需处于运行状态,以便测试服务器能够建立连接。
另一个测试是检查 NAT 穿透能力。该测试对服务器和客户端均有效,
而且无需事先设置就可以进行测试。NAT 测试会有 4 种结果(请参阅 ConnectionTesterStatus):__Full Cone_、Address Restricted Cone、Port restricted 及
Symmetric。
前两种提供完全 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"; } } }