public void Connect(string host = "0.0.0.0", ushort port = DEFAULT_PORT, string natHost = "", ushort natPort = NatHolePunch.DEFAULT_NAT_SERVER_PORT) { if (Disposed) { throw new ObjectDisposedException("UDPServer", "此对象已被处置且不能用于连接,请使用新的UDPServer。This object has been disposed and can not be used to connect, please use a new UDPServer"); } try { Client = new CachedUdpClient(port); Client.EnableBroadcast = true; Me = new NetworkingPlayer(ServerPlayerCounter++, host, true, ResolveHost(host, port), this); Me.InstanceGuid = InstanceGuid.ToString(); //在成功绑定的结果中执行任何通用初始化 // Do any generic initialization in result of the successful bind OnBindSuccessful(); //创建将监听来自连接客户端的新数据并开始执行的线程 // Create the thread that will be listening for new data from connected clients and start its execution Task.Queue(ReadClients); // 创建将检查播放器超时的线程 // Create the thread that will check for player timeouts Task.Queue(() => { commonServerLogic.CheckClientTimeout((player) => { Disconnect(player, true); OnPlayerTimeout(player); CleanupDisconnections(); }); }); //让我知道我连接成功 //Let myself know I connected successfully OnPlayerConnected(Me); //将自己设置为连接的客户端 // Set myself as a connected client Me.Connected = true; //Set the port SetPort((ushort)((IPEndPoint)Client.Client.LocalEndPoint).Port); if (!string.IsNullOrEmpty(natHost)) { nat.Register((ushort)Me.IPEndPointHandle.Port, natHost, natPort); nat.clientConnectAttempt += NatClientConnectAttempt; } } catch (Exception e) { Logging.BMSLog.LogException(e); // Do any generic initialization in result of the binding failure OnBindFailure(); throw new FailedBindingException("Failed to bind to host/port, see inner exception", e); } }
/// <summary> /// A method to find all of the local UDP servers and clients on the network /// </summary> public static void RefreshLocalUdpListings(ushort portNumber = DEFAULT_PORT, int responseBuffer = 1000) { CloseLocalListingsClient(); if (LocalEndpoints == null) { LocalEndpoints = new List <BroadcastEndpoints>(); } else { lock (LocalEndpoints) { LocalEndpoints.Clear(); } } foreach (IPAddress ipAddress in GetLocalIPs()) { // Create a client to write on the network and discover other clients and servers CachedUdpClient localListingsClient = new CachedUdpClient(new IPEndPoint(ipAddress, 19375)); localListingsClient.EnableBroadcast = true; AddNewLocalListingClient(localListingsClient); Task.Queue(CloseLocalListingsClient, responseBuffer); Task.Queue(() => { SendFindLocalNetworkBroadcast(localListingsClient, portNumber); }); } }
private static void AddNewLocalListingClient(CachedUdpClient localListingsClient) { lock (localListingsClientList) { localListingsClientList.Add(localListingsClient); } }
private ushort FindAvailablePort(ushort clientPort, ushort port) { if (clientPort == port) { clientPort++; } for (; ; clientPort++) { try { Client = new CachedUdpClient(clientPort); break; } catch { if (port == 0) { throw new BaseNetworkException("There were no ports available starting from port " + port); } } } return(clientPort); }
/// <summary> /// A method to find all of the local UDP servers and clients on the network /// </summary> public static void RefreshLocalUdpListings(ushort portNumber = DEFAULT_PORT, int responseBuffer = 1000) { // Initialize the list to hold all of the local network endpoints that respond to the request if (LocalEndpoints == null) { LocalEndpoints = new List <BroadcastEndpoints>(); } // Make sure to clear out the existing endpoints lock (LocalEndpoints) { LocalEndpoints.Clear(); } // Create a client to write on the network and discover other clients and servers localListingsClient = new CachedUdpClient(19375); localListingsClient.EnableBroadcast = true; Task.Queue(() => { CloseLocalListingsClient(); }, responseBuffer); Task.Queue(() => { IPEndPoint groupEp = default(IPEndPoint); string endpoint = string.Empty; localListingsClient.Send(new byte[] { BROADCAST_LISTING_REQUEST_1, BROADCAST_LISTING_REQUEST_2, BROADCAST_LISTING_REQUEST_3 }, 3, new IPEndPoint(IPAddress.Parse("255.255.255.255"), portNumber)); try { while (localListingsClient != null && !EndingSession) { var data = localListingsClient.Receive(ref groupEp, ref endpoint); if (data.Size != 1) { continue; } string[] parts = endpoint.Split('+'); string address = parts[0]; ushort port = ushort.Parse(parts[1]); if (data[0] == SERVER_BROADCAST_CODE) { var ep = new BroadcastEndpoints(address, port, true); LocalEndpoints.Add(ep); if (localServerLocated != null) { localServerLocated(ep); } } else if (data[0] == CLIENT_BROADCAST_CODE) { LocalEndpoints.Add(new BroadcastEndpoints(address, port, false)); } } } catch { } }); }
private static void CloseLocalListingsClient() { if (localListingsClient != null) { localListingsClient.Close(); localListingsClient = null; } }
private static void ReceiveFromFindLocalNetworkBroadcast(CachedUdpClient localListingsClient) { IPEndPoint groupEp = default; string endpoint = string.Empty; var data = localListingsClient.Receive(ref groupEp, ref endpoint); if (data.Size != 1) { return; } ParseFindLocalNetworkBroadcastResponse(endpoint, data); }
public static void SetupLocalUdpListings() { if (LocalConnections == null) { LocalConnections = new List <BroadcastEndpoints>(); } lock (LocalConnections) { LocalConnections.Clear(); } localListingsClient = new CachedUdpClient(19375); localListingsClient.EnableBroadcast = true; Task.Queue(() => { CloseLocalListingsClient(); }, 1000); Task.Queue(() => { IPEndPoint groupEp = default(IPEndPoint); string endpoint = string.Empty; localListingsClient.Send(new byte[] { BROADCAST_LISTING_REQUEST_1, BROADCAST_LISTING_REQUEST_2, BROADCAST_LISTING_REQUEST_3 }, 3, new IPEndPoint(IPAddress.Parse("255.255.255.255"), DEFAULT_PORT)); try { while (localListingsClient != null && !ExitingApplication) { var data = localListingsClient.Receive(ref groupEp, ref endpoint); if (data.Size != 1) { continue; } string[] parts = endpoint.Split('+'); string address = parts[0]; ushort port = ushort.Parse(parts[1]); if (data[0] == SERVER_BROADCAST_CODE) { LocalConnections.Add(new BroadcastEndpoints(address, port, true)); } else if (data[0] == CLIENT_BROADCAST_CODE) { LocalConnections.Add(new BroadcastEndpoints(address, port, false)); } } } catch { } }); }
private static void SendFindLocalNetworkBroadcast(CachedUdpClient localListingsClient, ushort portNumber) { localListingsClient.Send(new byte[] { BROADCAST_LISTING_REQUEST_1, BROADCAST_LISTING_REQUEST_2, BROADCAST_LISTING_REQUEST_3 }, 3, new IPEndPoint(IPAddress.Parse("255.255.255.255"), portNumber)); try { while (localListingsClient != null && !EndingSession) { ReceiveFromFindLocalNetworkBroadcast(localListingsClient); } } catch { } }
private static bool checkToCloseLocalListingClient(CachedUdpClient client, int responseBuffer = 1000) { if (client.createTime.AddMilliseconds(responseBuffer) < DateTime.Now) { BeardedManStudios.Forge.Logging.BMSLog.Log("CLOSING local Listing client"); lock (localListingsClientList) { client.Client.Close(); localListingsClientList.Remove(client); } return(true); } BeardedManStudios.Forge.Logging.BMSLog.Log("local Listing client remains open; time left: " + client.createTime.Subtract(DateTime.Now)); return(false); }
public void Connect(string host = "0.0.0.0", ushort port = DEFAULT_PORT, string natHost = "", ushort natPort = NatHolePunch.DEFAULT_NAT_SERVER_PORT) { try { Client = new CachedUdpClient(port); Client.EnableBroadcast = true; Me = new NetworkingPlayer(ServerPlayerCounter++, host, true, ResolveHost(host, port), this); Me.InstanceGuid = InstanceGuid.ToString(); // Create the thread that will be listening for new data from connected clients and start its execution Task.Queue(ReadClients); // Create the thread that will check for player timeouts Task.Queue(CheckClientTimeout); // Do any generic initialization in result of the successful bind OnBindSuccessful(); //Let myself know I connected successfully OnPlayerConnected(Me); // Set myself as a connected client Me.Connected = true; //Set the port SetPort((ushort)((IPEndPoint)Client.Client.LocalEndPoint).Port); if (!string.IsNullOrEmpty(natHost)) { nat.Register((ushort)Me.IPEndPointHandle.Port, natHost, natPort); nat.clientConnectAttempt += NatClientConnectAttempt; } } catch (Exception e) { Logging.BMSLog.LogException(e); // Do any generic initialization in result of the binding failure OnBindFailure(); throw new FailedBindingException("Failed to bind to host/port, see inner exception", e); } }
/// <summary> /// A method to find all of the local UDP servers and clients on the network /// </summary> public static void RefreshLocalUdpListings(ushort portNumber = DEFAULT_PORT, int responseBuffer = 1000) { lock (localListingsClientList) { foreach (CachedUdpClient cachedUdpClient in localListingsClientList) { cachedUdpClient.Client.Close(); } localListingsClientList.Clear(); } // Initialize the list to hold all of the local network endpoints that respond to the request if (LocalEndpoints == null) { LocalEndpoints = new List <BroadcastEndpoints>(); } // Make sure to clear out the existing endpoints lock (LocalEndpoints) { LocalEndpoints.Clear(); } foreach (IPAddress ipAddress in GetLocalIPs()) { // Create a client to write on the network and discover other clients and servers CachedUdpClient localListingsClient = new CachedUdpClient(new IPEndPoint(ipAddress, portNumber)); localListingsClient.createTime = DateTime.Now; localListingsClient.EnableBroadcast = true; lock (localListingsClientList) { localListingsClientList.Add(localListingsClient); } Task.Queue(() => { CloseLocalListingsClient(); }, responseBuffer); Task.Queue(() => { IPEndPoint groupEp = default(IPEndPoint); string endpoint = string.Empty; localListingsClient.Send(new byte[] { BROADCAST_LISTING_REQUEST_1, BROADCAST_LISTING_REQUEST_2, BROADCAST_LISTING_REQUEST_3 }, 3, new IPEndPoint(IPAddress.Parse("255.255.255.255"), portNumber)); try { while (localListingsClient != null && !EndingSession) { localListingsClient.ReceiveLanDiscovery(ref groupEp, ref endpoint, ipAddress.ToString(), Convert.ToInt32(portNumber)); } } catch (ObjectDisposedException disposedEx) { //BeardedManStudios.Forge.Logging.BMSLog.Log("Socket is disposed already."); //lastDebugMessage = "Socket is disposed"; } catch (Exception e) { //BeardedManStudios.Forge.Logging.BMSLog.Log("Exception Caught message: " + e.ToString()); //lastDebugMessage = e.ToString(); } }); } }
/// <summary> /// This will connect a UDP client to a given UDP server /// </summary> /// <param name="host">The server's host address on the network</param> /// <param name="port">The port that the server is hosting on</param> /// <param name="natHost">The NAT server host address, if blank NAT will be skipped</param> /// <param name="natPort">The port that the NAT server is hosting on</param> /// <param name="pendCreates">Immidiately set the NetWorker::PendCreates to true</param> public void Connect(string host, ushort port = DEFAULT_PORT, string natHost = "", ushort natPort = NatHolePunch.DEFAULT_NAT_SERVER_PORT, bool pendCreates = false, ushort overrideBindingPort = DEFAULT_PORT + 1) { if (Disposed) { throw new ObjectDisposedException("UDPClient", "This object has been disposed and can not be used to connect, please use a new UDPClient"); } // By default pending creates should be true and flushed when ready if (!pendCreates) { PendCreates = true; } try { ushort clientPort = overrideBindingPort; // Make sure not to listen on the same port as the server for local networks if (clientPort == port) { clientPort++; } for (; ; clientPort++) { try { Client = new CachedUdpClient(clientPort); break; } catch { if (port == 0) { throw new BaseNetworkException("There were no ports available starting from port " + port); } } } Client.EnableBroadcast = true; // If the server is behind a NAT, request for the port punch by the nat server if (!string.IsNullOrEmpty(natHost)) { nat.Connect(host, port, clientPort, natHost, natPort); } // Do any generic initialization in result of the successful bind OnBindSuccessful(); // Get a random hash key that needs to be used for validating that the server was connected to headerHash = Websockets.HeaderHashKey(); // This is a typical Websockets accept header to be validated byte[] connectHeader = Websockets.ConnectionHeader(headerHash, port); try { // Setup the identity of the server as a player server = new NetworkingPlayer(0, host, true, ResolveHost(host, port), this); } catch (ArgumentException) { if (connectAttemptFailed != null) { connectAttemptFailed(this); } throw; } // Create the thread that will be listening for new data from connected clients and start its execution Task.Queue(ReadNetwork); //Let myself know I connected successfully OnPlayerConnected(server); // Set myself as a connected client server.Connected = true; //Set the port SetPort(clientPort); int connectCounter = 0; Task.Queue(() => { do { // Send the accept headers to the server to validate Client.Send(connectHeader, connectHeader.Length, Server.IPEndPointHandle); Thread.Sleep(3000); } while (!headerExchanged && IsBound && ++connectCounter < CONNECT_TRIES); if (connectCounter >= CONNECT_TRIES) { if (connectAttemptFailed != null) { connectAttemptFailed(this); } } }); } catch (Exception e) { Logging.BMSLog.LogException(e); // Do any generic initialization in result of the binding failure OnBindFailure(); throw new FailedBindingException("Failed to bind to host/port, see inner exception", e); } }
public void Connect(string host, ushort port = DEFAULT_PORT, string natHost = "", ushort natPort = NatHolePunch.DEFAULT_NAT_SERVER_PORT, bool isSpecial = false) { // By default pending creates should be true and flushed when ready if (!isSpecial) { PendCreates = true; } try { // TODO: Remove + 1, it is for linux tests ushort clientPort = port; //(ushort)(port + 1); for (; ; clientPort++) { try { Client = new CachedUdpClient(clientPort); break; } catch { if (port == 0) { throw new BaseNetworkException("There were no ports available starting from port " + port); } } } Client.EnableBroadcast = true; // If the server is behind a NAT, request for the port punch by the nat server if (!string.IsNullOrEmpty(natHost)) { nat.Connect(host, port, clientPort, natHost, natPort); } // Do any generic initialization in result of the successful bind OnBindSuccessful(); // Get a random hash key that needs to be used for validating that the server was connected to headerHash = Websockets.HeaderHashKey(); // This is a typical Websockets accept header to be validated byte[] connectHeader = Websockets.ConnectionHeader(headerHash, port); // Setup the identity of the server as a player server = new NetworkingPlayer(0, host, true, ResolveHost(host, port), this); // Create the thread that will be listening for new data from connected clients and start its execution Task.Queue(ReadNetwork); //Let myself know I connected successfully OnPlayerConnected(server); // Set myself as a connected client server.Connected = true; //Set the port SetPort(clientPort); Task.Queue(() => { do { // Send the accept headers to the server to validate Client.Send(connectHeader, connectHeader.Length, Server.IPEndPointHandle); Thread.Sleep(3000); } while (!headerExchanged && IsBound); }); } catch (Exception e) { Logging.BMSLog.LogException(e); // Do any generic initialization in result of the binding failure OnBindFailure(); throw new FailedBindingException("Failed to bind to host/port, see inner exception", e); } }