コード例 #1
0
        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);
            }
        }
コード例 #2
0
ファイル: NetWorker.cs プロジェクト: MentalRefinery/Cha-Cha
        /// <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);
                });
            }
        }
コード例 #3
0
ファイル: NetWorker.cs プロジェクト: MentalRefinery/Cha-Cha
 private static void AddNewLocalListingClient(CachedUdpClient localListingsClient)
 {
     lock (localListingsClientList)
     {
         localListingsClientList.Add(localListingsClient);
     }
 }
コード例 #4
0
ファイル: UDPClient.cs プロジェクト: MentalRefinery/Cha-Cha
        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);
        }
コード例 #5
0
        /// <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 { }
            });
        }
コード例 #6
0
 private static void CloseLocalListingsClient()
 {
     if (localListingsClient != null)
     {
         localListingsClient.Close();
         localListingsClient = null;
     }
 }
コード例 #7
0
ファイル: NetWorker.cs プロジェクト: MentalRefinery/Cha-Cha
        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);
        }
コード例 #8
0
        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 { }
            });
        }
コード例 #9
0
ファイル: NetWorker.cs プロジェクト: MentalRefinery/Cha-Cha
        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 { }
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
            }
        }
コード例 #12
0
        /// <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();
                    }
                });
            }
        }
コード例 #13
0
        /// <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);
            }
        }
コード例 #14
0
        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);
            }
        }