Exemplo n.º 1
0
        public void TestConnectCallsDelegate()
        {
            bool serverActionCalled = false;
            bool clientActionCalled = false;

            void saveServerState(SocketState x)
            {
                testLocalSocketState = x;
                serverActionCalled   = true;
            }

            void saveClientState(SocketState x)
            {
                testRemoteSocketState = x;
                clientActionCalled    = true;
            }

            testListener = Networking.StartServer(saveServerState, 2112);
            Networking.ConnectToServer(saveClientState, "localhost", 2112);
            NetworkTestHelper.WaitForOrTimeout(() => serverActionCalled, NetworkTestHelper.timeout);
            NetworkTestHelper.WaitForOrTimeout(() => clientActionCalled, NetworkTestHelper.timeout);

            Assert.IsTrue(serverActionCalled);
            Assert.IsTrue(clientActionCalled);
        }
Exemplo n.º 2
0
        public void TestMultipleClientConnections()
        {
            SocketState state = new SocketState(null, null);
            int         i     = 0;
            int         j     = 0;

            void toServerCall(SocketState s)
            {
                i++;
            }

            void toClientCall(SocketState s)
            {
                j++;
                NetworkTestHelper.WaitForOrTimeout(() => false, 2000);
                Assert.IsTrue(i == j);
            }

            TcpListener listener = Networking.StartServer(toServerCall, 2112);

            Networking.ConnectToServer(toClientCall, "localhost", 2112);
            Networking.ConnectToServer(toClientCall, "localhost", 2112);
            Networking.ConnectToServer(toClientCall, "localhost", 2112);
            Networking.ConnectToServer(toClientCall, "localhost", 2112);
            Networking.ConnectToServer(toClientCall, "localhost", 2112);
        }
Exemplo n.º 3
0
        public void TestConnectWithIPV6()
        {
            bool isCalled           = false;
            bool serverActionCalled = false;

            void saveClientState(SocketState x)
            {
                isCalled             = true;
                testLocalSocketState = x;
            }

            void saveServerState(SocketState x)
            {
                testLocalSocketState = x;
                serverActionCalled   = true;
            }

            testListener = Networking.StartServer(saveServerState, 2112);

            // Try to connect without setting up a server first.
            Networking.ConnectToServer(saveClientState, "ipv6.google.com", 2112);
            // NetworkTestHelper.WaitForOrTimeout(() => isCalled, NetworkTestHelper.timeout);

            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
            Assert.AreEqual("IPV4 addresses were not found", testLocalSocketState.ErrorMessage);
        }
Exemplo n.º 4
0
        public void TestConnectToServerErrorNoServerExists()
        {
            void toCall(SocketState s)
            {
                testLocalSocketState = s;
            }

            Networking.ConnectToServer(toCall, "localhost", 2134);

            NetworkTestHelper.WaitForOrTimeout(() => false, 3000);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
        }
Exemplo n.º 5
0
        public void TestConnectToServerError1()
        {
            SocketState state = new SocketState(null, null);

            void toCall(SocketState s)
            {
                state = s;
            }

            Networking.ConnectToServer(toCall, "bjknnjkljkn;sfghj[{{{{{adf <><>asdfdeb098u]]]]]xxx.<>", 2130);

            Assert.IsTrue(state.ErrorOccured);
        }
Exemplo n.º 6
0
        public void TestConnectToServerError2()
        {
            SocketState state = new SocketState(null, null);

            void toCall(SocketState s)
            {
                state = s;
            }

            Networking.ConnectToServer(toCall, null, 2131);

            Assert.IsTrue(state.ErrorOccured);
        }
Exemplo n.º 7
0
        public void TestFalseNumericalIPAdddress(bool clientSide)
        {
            bool errorOccurred = false;

            void emptySS(SocketState state)
            {
                testLocalSocketState = state;
                errorOccurred        = true;
            }

            Networking.ConnectToServer(emptySS, "127.0.3.1", 11000);

            Assert.IsTrue(testLocalSocketState.ErrorOccured);
            Assert.IsTrue(errorOccurred);
        }
Exemplo n.º 8
0
        private TcpListener SetupSingleClientTest()
        {
            Action <SocketState> saveState =
                x =>
            {
                testLocalSocketState = x;
                testLocalSocketState.OnNetworkAction = s => { };
            };
            TcpListener listener = StartTestServer(2112);

            Networking.ConnectToServer(saveState, "localhost", 2112);

            WaitForOrTimeout(() => (testLocalSocketState != null) && (testRemoteSocketState != null), timeout);

            return(listener);
        }
Exemplo n.º 9
0
        public void TestConnectTimeout()
        {
            bool isCalled = false;

            void saveClientState(SocketState x)
            {
                isCalled             = true;
                testLocalSocketState = x;
            }

            Networking.ConnectToServer(saveClientState, "google.com", 2112);
            WaitForOrTimeout(() => isCalled, timeout);

            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
        }
Exemplo n.º 10
0
        public void TestStopServer()
        {
            void saveServerState(SocketState x)
            {
                testLocalSocketState = x;
            }

            void saveClientState(SocketState x)
            {
                testLocalSocketState = x;
            }

            testListener = Networking.StartServer(saveServerState, 2112);
            Networking.ConnectToServer(saveClientState, "localhost", 2112);
            Assert.IsTrue(testLocalSocketState.TheSocket.Connected);
            Networking.StopServer(testListener);
        }
Exemplo n.º 11
0
        public void TestStopServer()
        {
            NetworkTestHelper.SetupSingleConnectionTest(
                out testListener,
                out testRemoteSocketState,
                out testLocalSocketState, 2200);

            Networking.StopServer(testListener);

            SocketState newState = new SocketState(null, null);

            Networking.ConnectToServer(s => newState = s, "localhost", 2200);

            NetworkTestHelper.WaitForOrTimeout(() => false, 3000);

            Assert.IsTrue(newState.ErrorOccured);
        }
Exemplo n.º 12
0
        public void TestConnectNoServer()
        {
            bool isCalled = false;

            void saveClientState(SocketState x)
            {
                isCalled             = true;
                testLocalSocketState = x;
            }

            // Try to connect without setting up a server first.
            Networking.ConnectToServer(saveClientState, "localhost", 2126);
            NetworkTestHelper.WaitForOrTimeout(() => isCalled, NetworkTestHelper.timeout);

            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
        }
Exemplo n.º 13
0
        public void TestClose()
        {
            NetworkTestHelper.SetupSingleConnectionTest(out testListener, out testLocalSocketState, out testRemoteSocketState);
            Networking.StopServer(testListener);

            SocketState client = null;

            void SaveClient(SocketState s)
            {
                client = s;
            }

            //Using port 2112 because it is the same port being used in SetupSingleConnectionTest method use
            //Should produce a ErrorOccured SocketState because we have closed hearing any incoming connections
            Networking.ConnectToServer(SaveClient, "localhost", 2112);
            Assert.IsTrue(client.ErrorOccured);
        }
Exemplo n.º 14
0
        public void TestConnectToServerIPV4Address()
        {
            bool isCalled = false;

            void saveClientState(SocketState x)
            {
                isCalled             = true;
                testLocalSocketState = x;
            }

            NetworkTestHelper.SetupSingleConnectionTest(out testListener, out testLocalSocketState, out testRemoteSocketState);

            Networking.ConnectToServer(saveClientState, "192.168.0.19", 2112);
            NetworkTestHelper.WaitForOrTimeout(() => isCalled, 1000);

            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
        }
Exemplo n.º 15
0
        public void TestConnectToServerinvaildIPadress()
        {
            bool isCalled = false;

            void saveClientState(SocketState x)
            {
                isCalled             = true;
                testLocalSocketState = x;
            }

            NetworkTestHelper.SetupSingleConnectionTest(out testListener, out testLocalSocketState, out testRemoteSocketState);

            Networking.ConnectToServer(saveClientState, "3731:54:65fe:2:  :a7/64", 2112);
            NetworkTestHelper.WaitForOrTimeout(() => isCalled, NetworkTestHelper.timeout);

            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
        }
Exemplo n.º 16
0
        public void ConnectToServer_BeginConnectWillStartButThenTimeout_ShouldInvokeToCallDelegateOnce()
        {
            bool isCalled       = false;
            int  numTimesCalled = 0;

            void saveClientState(SocketState x)
            {
                isCalled = true;
                numTimesCalled++;
                testLocalSocketState = x;
            }

            Networking.ConnectToServer(saveClientState, "google.com", 2112);
            NetworkTestHelper.WaitForOrTimeout(() => isCalled, NetworkTestHelper.timeout);
            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
            Assert.AreEqual(1, numTimesCalled);
        }
Exemplo n.º 17
0
        public void ConnectToServer_HostNameIsInvalidIPAddress_ShouldReturnErrorSocketStateAndInvokeToCallDelegateOnce()
        {
            bool isCalled       = false;
            int  numTimesCalled = 0;

            void saveClientState(SocketState x)
            {
                isCalled = true;
                numTimesCalled++;
                testLocalSocketState = x;
            }

            Networking.ConnectToServer(saveClientState, "ybxiciwjwlpdooyqwwesxnvlezxiqe.com", 2112);
            NetworkTestHelper.WaitForOrTimeout(() => isCalled, NetworkTestHelper.timeout);
            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
            Assert.AreEqual(1, numTimesCalled);
        }
Exemplo n.º 18
0
        public void ConnectToServer_CouldNotFindIPV4Address_ShouldReturnErrorSocketStateAndInvokeToCallDelegateOnce()
        {
            bool isCalled       = false;
            int  numTimesCalled = 0;

            void saveClientState(SocketState x)
            {
                isCalled = true;
                numTimesCalled++;
                testLocalSocketState = x;
            }

            Networking.ConnectToServer(saveClientState, "ipv6.google.com", 2112);
            NetworkTestHelper.WaitForOrTimeout(() => isCalled, NetworkTestHelper.timeout);
            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
            Assert.AreEqual(1, numTimesCalled);
        }
Exemplo n.º 19
0
        public void TestConnectTimeout()
        {
            bool isCalled = false;

            void saveClientState(SocketState x)
            {
                isCalled             = true;
                testLocalSocketState = x;
            }

            Networking.ConnectToServer(saveClientState, "google.com", 2112);

            // The connection should timeout after 3 seconds. NetworkTestHelper.timeout is 5 seconds.
            NetworkTestHelper.WaitForOrTimeout(() => isCalled, NetworkTestHelper.timeout);

            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
        }
Exemplo n.º 20
0
        public void ConnectToServer_ErrorOccursDuringSocketBeginConnect_ShouldReturnErrorSocketStateAndInvokeToCallDelegateOnce()
        {
            bool isCalled       = false;
            int  numTimesCalled = 0;

            void saveClientState(SocketState x)
            {
                isCalled = true;
                numTimesCalled++;
                testLocalSocketState = x;
            }

            Networking.ConnectToServer(saveClientState, "localhost", 99999999);
            NetworkTestHelper.WaitForOrTimeout(() => isCalled, NetworkTestHelper.timeout);
            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
            Assert.AreEqual(1, numTimesCalled);
        }
Exemplo n.º 21
0
        public void TestConnectStartAndStopNoServer()
        {
            bool isCalled = false;

            void saveClientState(SocketState x)
            {
                isCalled             = true;
                testLocalSocketState = x;
            }

            NetworkTestHelper.SetupSingleConnectionTest(out testListener, out testLocalSocketState, out testRemoteSocketState);
            Networking.StopServer(testListener);
            // Try to connect without setting up a server first.
            Networking.ConnectToServer(saveClientState, "localhost", 2112);
            NetworkTestHelper.WaitForOrTimeout(() => isCalled, NetworkTestHelper.timeout);

            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
        }
Exemplo n.º 22
0
        private TcpListener SetupSingleServerTest()
        {
            void saveServerState(SocketState x)
            {
                testLocalSocketState = x;
                testLocalSocketState.OnNetworkAction = s => { };
            }

            void saveClientState(SocketState x)
            {
                testRemoteSocketState = x;
            }

            TcpListener listener = Networking.StartServer(saveServerState, 2112);

            Networking.ConnectToServer(saveClientState, "localhost", 2112);

            WaitForOrTimeout(() => (testLocalSocketState != null) && (testRemoteSocketState != null), timeout);
            return(listener);
        }
Exemplo n.º 23
0
        public void TestConnectCallsDelegate()
        {
            bool isCalled = false;

            void saveServerState(SocketState x)
            {
                testLocalSocketState = x;
                isCalled             = true;
            }

            void saveClientState(SocketState x)
            {
                testRemoteSocketState = x;
            }

            testListener = Networking.StartServer(saveServerState, 2112);
            Networking.ConnectToServer(saveClientState, "localhost", 2112);
            WaitForOrTimeout(() => isCalled, timeout);

            Assert.IsTrue(isCalled);
        }
Exemplo n.º 24
0
        public static void SetupSingleConnectionTest(out TcpListener listener, out SocketState client, out SocketState server, int port)
        {
            SocketState clientResult = null;
            SocketState serverResult = null;

            void saveClientState(SocketState x)
            {
                clientResult = x;
            }

            void saveServerState(SocketState x)
            {
                serverResult = x;
            }

            listener = Networking.StartServer(saveServerState, port);
            Networking.ConnectToServer(saveClientState, "localhost", port);

            WaitForOrTimeout(() => (clientResult != null) && (serverResult != null), timeout);
            client = clientResult;
            server = serverResult;
        }
Exemplo n.º 25
0
        public void TestConnectToServerIPV6Address()
        {
            bool isCalled = false;

            void saveClientState(SocketState x)
            {
                isCalled             = true;
                testLocalSocketState = x;
            }

            NetworkTestHelper.SetupSingleConnectionTest(out testListener, out testLocalSocketState, out testRemoteSocketState);


            Networking.ConnectToServer(saveClientState, "2602:41:8182:68ff:58ec:52fc:8711:b430", 2112);
            //   Networking.ConnectToServer(saveClientState, "fd00::58ec:52fc:8711:b430", 2112);
            //Networking.ConnectToServer(saveClientState, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", 2112);

            NetworkTestHelper.WaitForOrTimeout(() => isCalled, 1000);

            Assert.IsTrue(isCalled);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
        }
Exemplo n.º 26
0
        public void TestConnectToServerError3()
        {
            string message   = "this message here";
            bool   firstTime = true;
            int    times     = 0;

            void toCall(SocketState s)
            {
                times++;
                testLocalSocketState = s;
                if (firstTime)
                {
                    firstTime = false;
                    throw new Exception(message);
                }
            }

            testListener = Networking.StartServer(s => { }, 2134);
            Networking.ConnectToServer(toCall, "localhost", 2134);

            NetworkTestHelper.WaitForOrTimeout(() => false, 3000);
            Assert.IsTrue(testLocalSocketState.ErrorOccured);
            Assert.IsTrue(testLocalSocketState.ErrorMessage.Equals(message));
        }
Exemplo n.º 27
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();
        }
Exemplo n.º 28
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());
        }
Exemplo n.º 29
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;
        }
Exemplo n.º 30
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);
        }