Esempio n. 1
0
        /// <summary>
        /// Handles newly connected client.
        /// </summary>
        /// <param name="client">Incoming socket</param>
        /// <param name="ID">ID of the client</param>
        /// <returns>Task that completes when the client has been handled.</returns>
        async Task HandleClientConnectionAssync(Socket client, int ID, ConnectingStaticData con)
        {
            Console.WriteLine($"Connectd to {ID}({client.RemoteEndPoint})");
            await Communication.TCPSendMessageAsync(client, ConnectingStaticData.Encode(con));

            bool clientReady = await Communication.TCPReceiveACKAsync(client);

            Console.WriteLine($"Recieved ACK from {ID}");
            Debug.Assert(clientReady);
            ReadyClient c = new ReadyClient
            {
                playerID         = con.PlayerID,
                dynDataSocket    = client,
                relUpdatesSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp),
            };
            //Establish a channel for reliable updates.
            //TEMP Shift ports by playerID=Allows multiple clients on one computer
            var relAddress = new IPEndPoint((c.dynDataSocket.RemoteEndPoint as IPEndPoint).Address, Ports.relServerUpdates + con.PlayerID);

            c.relUpdatesSocket.Connect(relAddress);
            Console.WriteLine($"Created a reliable channel for server commands fro {ID}.");
            var tmp = readyClients;

            while (tmp != Interlocked.CompareExchange(ref readyClients, tmp.Add(c), tmp))
            {
                tmp = readyClients;
            }

            Console.WriteLine($"{ID} is ready");
        }
Esempio n. 2
0
        /// <summary>
        /// Adds client to connectedClients then asynchronously sends the dynamic data to them and disconnects the socket.
        /// </summary>
        /// <returns>Task that finishes when the message has been sent.</returns>
        async Task ProcessReadyClient(ReadyClient c, byte[] dynamicData)
        {
            var cc = new ConnectedClient
            {
                playerID          = c.playerID,
                timeoutTicks      = 0,
                relUpdateSocket   = c.relUpdatesSocket,
                lastPolledCUpdate = 0,
            };

            Debug.Assert(c.dynDataSocket.RemoteEndPoint is IPEndPoint, "Socket should use IP for communication,");
            //Use address from previous connection.
            //TEMP Shift ports by playerID=Allows multiple clients on one computer
            cc.updateAddress = new IPEndPoint((c.dynDataSocket.RemoteEndPoint as IPEndPoint).Address, Ports.serverUpdates + c.playerID);
            connectedClients.Add(cc.playerID, cc);
            Console.WriteLine($"Client {cc.playerID} is now connected.");

            await Communication.TCPSendMessageAsync(c.dynDataSocket, dynamicData);

            c.dynDataSocket.Shutdown(SocketShutdown.Send);

            int read = c.dynDataSocket.Receive(new byte[5]);            //Wait until clients shutdowns its socket = dynamic data received.

            Debug.Assert(read == 0);
            Console.WriteLine($"Dynamic data for {cc.playerID} has been sent,closing connection.");
            c.dynDataSocket.Close();
        }
Esempio n. 3
0
        /// <summary>
        /// Sends a ServerCommand to a client from connectClients.
        /// </summary>
        /// <param name="pID">ID of the client.</param>
        /// <param name="cmd">Command to send.</param>
        public async Task SendServerCommandAsync(int pID, ServerCommand cmd)
        {
            if (connectedClients.TryGetValue(pID, out ConnectedClient client))
            {
                if (cmd.guaranteedExec)
                {
                    var bytes = Serialization.PrependInt(new CmdServerUpdate(cmd).Encode(), client.lastPolledCUpdate);
                    await Task.Delay(sendDelay);

                    await Communication.TCPSendMessageAsync(client.relUpdateSocket, bytes);
                }
                else
                {
                    var bytes = Serialization.PrependInt(cmd.Encode(), client.lastPolledCUpdate);
                    if (random.NextDouble() < packetLoss)
                    {
                        return;
                    }
                    await Task.Delay(sendDelay);

                    await Communication.UDPSendMessageAsync(serverCommandsSender, client.updateAddress, bytes);
                }
            }
        }