Пример #1
0
        public void TestTwoServers()
        {
            SocketState server2          = null;
            SocketState client2          = null;
            bool        server2Connected = false;
            bool        receive1Called   = false;
            bool        receive2Called   = false;
            string      client1Message   = "";
            string      client2Message   = "";
            string      server1Message   = "";
            string      server2Message   = "";

            void Server2OnConnect(SocketState s)
            {
                if (s.ErrorOccured)
                {
                    return;
                }
                server2Connected        = true;
                server2                 = s;
                server2.OnNetworkAction = Server2OnReceive;
            }

            void Client2OnConnect(SocketState s)
            {
                if (s.ErrorOccured)
                {
                    return;
                }
                client2 = s;
            }

            void Server1OnReceive(SocketState s)
            {
                if (s.ErrorOccured)
                {
                    return;
                }
                receive1Called = true;
                server1Message = s.GetData();
            }

            void Server2OnReceive(SocketState s)
            {
                if (s.ErrorOccured)
                {
                    return;
                }
                receive2Called = true;
                server2Message = s.GetData();
            }

            void Client1OnReceive(SocketState s)
            {
                if (s.ErrorOccured)
                {
                    return;
                }
                receive1Called = true;
                client1Message = s.GetData();
            }

            void Client2OnReceive(SocketState s)
            {
                if (s.ErrorOccured)
                {
                    return;
                }
                receive2Called = true;
                client2Message = s.GetData();
            }

            // setup first server and client using the normal helper
            SetupTestConnections(false);
            testLocalSocketState.OnNetworkAction = Server1OnReceive;

            // setup second server and client
            TcpListener listener2 = Networking.StartServer(Server2OnConnect, 2222);

            Networking.ConnectToServer(Client2OnConnect, "localhost", 2222);

            // wait for the second pair to connect
            WaitForOrTimeout(() => server2 != null && client2 != null, timeout);

            // Receive on server1
            Networking.GetData(testLocalSocketState);
            // Receive on server2
            Networking.GetData(server2);

            // Receive on client1
            testRemoteSocketState.OnNetworkAction = Client1OnReceive;
            Networking.GetData(testRemoteSocketState);
            // Receive on client2
            client2.OnNetworkAction = Client2OnReceive;
            Networking.GetData(client2);

            // Send from client1 to server1
            Networking.Send(testRemoteSocketState.TheSocket, "a");

            // Send from client2 to server2
            Networking.Send(client2.TheSocket, "b");

            // Send from server1 to client1
            Networking.Send(testLocalSocketState.TheSocket, "c");

            // Send from server2to client2
            Networking.Send(server2.TheSocket, "d");

            WaitForOrTimeout(() => server2Connected && receive1Called && receive2Called, timeout);

            Assert.IsTrue(server2Connected);
            Assert.IsTrue(receive1Called);
            Assert.IsTrue(receive2Called);
            Assert.AreEqual("a", server1Message);
            Assert.AreEqual("b", server2Message);
            Assert.AreEqual("c", client1Message);
            Assert.AreEqual("d", client2Message);
        }
Пример #2
0
 private void StartReceiveLoop()
 {
     testRemoteSocketState.OnNetworkAction = ReceiveLoop;
     Networking.GetData(testRemoteSocketState);
 }
Пример #3
0
        private TcpListener StartTestServer(int port)
        {
            TcpListener listener = Networking.StartServer(OnNewClient, port);

            return(listener);
        }
Пример #4
0
        private void GameClients(
            out Dictionary <long, StringBuilder> clientSentMessages,
            out Dictionary <long, StringBuilder> clientReceivedMessages,
            out Dictionary <long, SocketState> clientSockets)
        {
            object clientConnectionsLock = new object();
            //Dictionary<long, SocketState> clientSocketStates = new Dictionary<long, SocketState>();
            Dictionary <long, StringBuilder> sentMessages     = new Dictionary <long, StringBuilder>();
            Dictionary <long, StringBuilder> receivedMessages = new Dictionary <long, StringBuilder>();
            Dictionary <long, SocketState>   sockets          = new Dictionary <long, SocketState>();
            Dictionary <long, Random>        randoms          = new Dictionary <long, Random>();
            Dictionary <long, long>          clientIDs        = new Dictionary <long, long>();
            Random rand = new Random(0);


            // Local function to serve as a callMe delegate
            void clientFirstContact(SocketState state)
            {
                if (state.ErrorOccured)
                {
                    return;
                }
                // Start a receive loop from the server
                state.OnNetworkAction = handleMessage;
                Networking.GetData(state);
            }

            // Local function to serve as a callMe delegate
            // Receive loop for the client that simualtes "processing" a message by
            // looking for a newline separator
            void handleMessage(SocketState state)
            {
                if (state.ErrorOccured)
                {
                    return;
                }
                lock (clientConnectionsLock)
                {
                    // If this is the first message, save the per-connection state for validating the test
                    if (!clientIDs.ContainsKey(state.ID))
                    {
                        // first message contains ID
                        clientIDs[state.ID] = int.Parse(state.GetData().Substring(0, state.GetData().IndexOf("\n") + 1));

                        sentMessages[clientIDs[state.ID]]     = new StringBuilder();
                        receivedMessages[clientIDs[state.ID]] = new StringBuilder();
                        sockets[clientIDs[state.ID]]          = state;
                        randoms[clientIDs[state.ID]]          = new Random((int)clientIDs[state.ID]);
                    }
                }


                StringBuilder rcv, sent;
                Random        rnd;

                lock (clientConnectionsLock)
                {
                    rcv  = receivedMessages[clientIDs[state.ID]];
                    sent = sentMessages[clientIDs[state.ID]];
                    rnd  = randoms[clientIDs[state.ID]];
                }

                ProcessMessage(state, rcv);

                // Decide if we will disconnect or not (1% chance)
                bool disconnect = rnd.Next(100) == 0;

                // Reply to the server about half of the time
                if (!disconnect && rnd.Next(2) == 0)
                {
                    StringBuilder reply = new StringBuilder();
                    for (int i = 0; i < rand.Next(10); i++)
                    {
                        reply.Append((char)('a' + rand.Next(26)));
                    }
                    reply.Append("\n");
                    sent.Append(reply);
                    Networking.Send(state.TheSocket, reply.ToString());
                }

                // Continue the receive loop or disconnect
                if (disconnect)
                {
                    state.TheSocket.Shutdown(SocketShutdown.Both);
                }
                else
                {
                    Networking.GetData(state);
                }
            }

            // Start a stopwatch to simulate clients connecting and disconnecting over time
            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            // 75 opportunities over time for clients to connect
            for (int i = 0; i < 75; i++)
            {
                // Connect 1 - 3 clients
                int numClients = 1 + rand.Next(3);
                for (int j = 0; j < numClients; j++)
                {
                    Networking.ConnectToServer(clientFirstContact, "localhost", 2112);
                }

                while (watch.ElapsedMilliseconds < 30)
                { /* just waiting */
                }

                watch.Restart();
            }

            clientSentMessages     = sentMessages;
            clientReceivedMessages = receivedMessages;
            clientSockets          = sockets;
        }
Пример #5
0
        private void GameServer(
            out Dictionary <long, StringBuilder> serverSentMessages,
            out Dictionary <long, StringBuilder> serverReceivedMessages)
        {
            object serverConnectionsLock = new object();
            Dictionary <long, SocketState>   serverSocketStates = new Dictionary <long, SocketState>();
            Dictionary <long, StringBuilder> sentMessages       = new Dictionary <long, StringBuilder>();
            Dictionary <long, StringBuilder> receivedMessages   = new Dictionary <long, StringBuilder>();
            Random rand = new Random(0);

            // Local function to serve as a callMe delegate
            void serverFirstContact(SocketState state)
            {
                if (state.ErrorOccured)
                {
                    return;
                }
                // Save the socket state so we can broadcast to all clients
                // Also save the rest of the per-connection state for validating the test
                lock (serverConnectionsLock)
                {
                    // Use one of the stringbuilder lists as a unique socket ID
                    // since they will strictly grow (the SocketState lists will grow and shrink)
                    //state.uid = sentMessages.Count;

                    sentMessages[state.ID]       = new StringBuilder();
                    receivedMessages[state.ID]   = new StringBuilder();
                    serverSocketStates[state.ID] = state;

                    // send the client's ID
                    // important to do this inside the lock so the broadcast loop doesn't
                    // run before sending the client's ID
                    sentMessages[state.ID].Append("" + state.ID + "\n");
                    Networking.Send(state.TheSocket, "" + state.ID + "\n");
                }

                // Start a receive loop from the client
                state.OnNetworkAction = removeMessage;
                Networking.GetData(state);
            }

            // Local function to serve as a callMe delegate
            // Receive loop for the server that just removes and saves the client's messages
            void removeMessage(SocketState state)
            {
                if (state.ErrorOccured)
                {
                    return;
                }
                StringBuilder rcv;

                lock (serverConnectionsLock)
                {
                    rcv = receivedMessages[state.ID];
                }

                rcv.Append(state.GetData());
                state.RemoveData(0, state.GetData().Length);
                Networking.GetData(state);
            }

            testListener = Networking.StartServer(serverFirstContact, 2112);

            // Start a stopwatch to simulate a game server's tick-rate
            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            int nextChar = 0;

            // Run for 150 frames
            for (int frame = 0; frame < 150; frame++)
            {
                // Create several messages ranging in size between 0x - 0.5x the buffer size,
                StringBuilder messages = new StringBuilder();
                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < rand.Next((int)(SocketState.BufferSize * 0.5)); j++)
                    {
                        messages.Append((char)('a' + (nextChar++ % 26)));
                    }

                    // Newline separator indicates end of object
                    messages.Append("\n");
                }

                lock (serverConnectionsLock)
                {
                    foreach (StringBuilder sb in sentMessages.Values)
                    {
                        sb.Append(messages);
                    }

                    foreach (SocketState ss in serverSocketStates.Values)
                    {
                        if (ss.TheSocket.Connected)
                        {
                            Networking.Send(ss.TheSocket, messages.ToString());
                        }
                    }
                }

                // Simulate slow-ish server that gives the clients enough time to receive
                // between frames so that we can assume that everything sent is also received
                while (watch.ElapsedMilliseconds < 30)
                { /* just waiting */
                }

                watch.Restart();
            } // end frame loop

            serverSentMessages     = sentMessages;
            serverReceivedMessages = receivedMessages;
        }
Пример #6
0
        public void TestSimulateClientAndServer()
        {
            // For this test, we will use testRemoteSocketState as the server's SocketState
            // and testLocalSocketState as the client's SocketState

            Random        rand           = new Random(0);
            StringBuilder serverReceived = new StringBuilder();
            StringBuilder clientReceived = new StringBuilder();
            StringBuilder clientSent     = new StringBuilder();

            // Local function to serve as a callMe delegate
            void serverFirstContact(SocketState state)
            {
                if (state.ErrorOccured)
                {
                    return;
                }
                // Save the socket state globally so that the Cleanup method can close it
                testRemoteSocketState = state;

                // Start a receive loop from the client
                state.OnNetworkAction = removeMessage;
                Networking.GetData(state);
            }

            // Local function to serve as a callMe delegate
            // Receive loop for the server that just removes and saves the client's messages
            void removeMessage(SocketState state)
            {
                if (state.ErrorOccured)
                {
                    return;
                }
                serverReceived.Append(state.GetData());
                state.RemoveData(0, state.GetData().Length);
                Networking.GetData(state);
            }

            // Local function to serve as a callMe delegate
            void clientFirstContact(SocketState state)
            {
                if (state.ErrorOccured)
                {
                    return;
                }
                // Save the socket state globally so that the Cleanup method can close it
                testLocalSocketState = state;

                // Start a receive loop from the server
                state.OnNetworkAction = handleMessage;
                Networking.GetData(state);
            }

            // Local function to serve as a callMe delegate
            // Receive loop for the client that simualtes "processing" a message by
            // looking for a newline separator
            void handleMessage(SocketState state)
            {
                if (state.ErrorOccured)
                {
                    return;
                }
                ProcessMessage(state, clientReceived);

                // Reply to the server about half of the time
                if (rand.Next(2) == 0)
                {
                    StringBuilder reply = new StringBuilder();
                    for (int i = 0; i < rand.Next(10); i++)
                    {
                        reply.Append((char)('a' + rand.Next(26)));
                    }
                    reply.Append("\n");
                    clientSent.Append(reply);
                    Networking.Send(state.TheSocket, reply.ToString());
                }

                // Continue the receive loop
                Networking.GetData(state);
            }

            // Start the listener
            testListener = Networking.StartServer(serverFirstContact, 2112);
            // Start the client
            Networking.ConnectToServer(clientFirstContact, "localhost", 2112);
            // Wait for both sides to connect
            WaitForOrTimeout(() => testLocalSocketState != null && testRemoteSocketState != null, timeout);

            // Run the server loop
            StringBuilder serverSent = SingleClientServerLoop();

            WaitForOrTimeout(() => clientReceived.Length == serverSent.Length, timeout);
            WaitForOrTimeout(() => clientSent.Length == serverReceived.Length, timeout);

            Assert.AreEqual(clientReceived.ToString(), serverSent.ToString());
            Assert.AreEqual(clientSent.ToString(), serverReceived.ToString());
        }
Пример #7
0
 public void TestSendNullMessage()
 {
     NetworkTestHelper.SetupSingleConnectionTest(out testListener, out testLocalSocketState, out testRemoteSocketState);
     //Sending null value, should causes a Error in the RemoteState
     Assert.IsFalse(Networking.Send(testRemoteSocketState.TheSocket, null));
 }
Пример #8
0
        public void TestMyOwn()
        {
            // List to represents connections
            List <SocketState> server = new List <SocketState>();

            void SaveServer(SocketState s)
            {
                lock (this)
                {
                    server.Add(s);
                }
            }

            //Two clients
            SocketState client_1 = null;

            void SaveClient_1(SocketState s)
            {
                client_1 = s;
            }

            SocketState client_2 = null;

            void SaveClient_2(SocketState s)
            {
                client_2 = s;
            }

            // Starting a server
            TcpListener listener = Networking.StartServer(SaveServer, 2112);

            // Client1 Connect to the server
            Networking.ConnectToServer(SaveClient_1, "localhost", 2112);

            // Client2 Connect to the server
            Networking.ConnectToServer(SaveClient_2, "localhost", 2112);

            // Make sure this line is what you want to it behave
            NetworkTestHelper.WaitForOrTimeout(() => (client_2 != null) && (client_1 != null) && (server.Count == 2), NetworkTestHelper.timeout);

            // Set the action to do nothing
            foreach (SocketState state in server)
            {
                state.OnNetworkAction = x => { };
            }

            client_1.OnNetworkAction = x => { };
            client_2.OnNetworkAction = x => { };

            foreach (SocketState state in server)
            {
                Networking.SendAndClose(state.TheSocket, "a");
            }

            Networking.GetData(client_1);
            Networking.GetData(client_2);


            // Note that waiting for data like this is *NOT* how the networking library is
            // intended to be used. This is only for testing purposes.
            // Normally, you would provide an OnNetworkAction that handles the data.
            NetworkTestHelper.WaitForOrTimeout(() => client_1.GetData().Length > 0 && client_2.GetData().Length > 0, NetworkTestHelper.timeout);

            Assert.AreEqual("a", client_1.GetData());
            Assert.AreEqual("a", client_2.GetData());

            //Make sure everything close and stop properly
            listener.Stop();
            foreach (SocketState state in server)
            {
                state.TheSocket.Close();
            }
            client_1.TheSocket.Close();
            client_2.TheSocket.Close();
        }