コード例 #1
0
        public void ConnectParallel()
        {
            // error occured in endpoint manager tests:
            // TcpClient lost connection after beeing used to instantiate a PacketSocket

            const int PORT = 2312;

            const int COUNT = 20;

            TcpClientListener listener = new();

            listener.StartListeningForConnections(PORT);

            List <Task>      tasks   = new();
            List <TcpClient> clients = new();

            for (int i = 0; i < COUNT; i++)
            {
                var c = new TcpClient();
                clients.Add(c);
                tasks.Add(Task.Run(() => c.Connect("localhost", PORT)));
            }
            Task.WaitAll(tasks.ToArray());

            clients.ForEach(c =>
            {
                Assert.IsTrue(c.Connected);
                PacketSocket s = new PacketSocket(c);
                Assert.IsTrue(s.IsConnected);
                Assert.IsTrue(s.IsReceiving);
            });
        }
コード例 #2
0
        private void ClientConnectedCallback(IAsyncResult ar)
        {
            if (!_running)
            {
                //listening for connections stopped
                _stopFinished.SetResult();
                return;
            }

            var tcpClient = _tcpListener.EndAcceptTcpClient(ar);

            log.Trace("incoming connection request");

            //prepare for next connect
            ListenForClients();

            //create socket and endpoint for new connection
            var socket   = new PacketSocket(tcpClient);
            var endpoint = new Endpoint(socket);

            log.Debug("connection request " + endpoint.Connection);

            var actionBlock = new ActionBlock <Tuple <IEndpoint, byte[]> >(ReceiveHandler);

            endpoint.MessageBlock.LinkTo(actionBlock);


            endpoint.Disconnected += Endpoint_Disconnected;

            _ = ConnectionHandler.ProcessEndpoint(endpoint.Connection, EndpointChangedEventArgs.NewConnection(endpoint));
        }
コード例 #3
0
        public void TestDisconnectedSend()
        {
            TcpClient    client = new();
            PacketSocket socket = new PacketSocket(client);

            byte[] payload = new byte[1024];

            TestUtils.AssertException <InvalidOperationException>(socket.SendAsync(payload));
        }
コード例 #4
0
        private void TestPacketSocket_communication(PacketSocket server, PacketSocket client)
        {
            const int PAYLOAD_SIZE = 1024;
            const int COUNT        = 100;

            Assert.IsTrue(server.IsConnected);
            Assert.IsTrue(client.IsConnected);

            byte[] payload = new byte[PAYLOAD_SIZE];

            for (int i = 0; i < payload.Length; i++)
            {
                payload[i] = (byte)i;
            }

            ActionBlock <byte[]> serverMessageBlock = new(buffer =>
            {
                CollectionAssert.AreEqual(payload, buffer);
            });
            ActionBlock <byte[]> clientMessageBlock = new(buffer =>
            {
                CollectionAssert.AreEqual(payload, buffer);
            });

            using var serverDisp = server.IncomingBufferBlock.LinkTo(serverMessageBlock);
            using var clientDisp = client.IncomingBufferBlock.LinkTo(clientMessageBlock);

            List <Task> taskList = new();

            for (int i = 0; i < COUNT; i++)
            {
                taskList.Add(Task.Run(async() =>
                {
                    Assert.IsTrue(await client.SendAsync(payload));
                }));
                taskList.Add(Task.Run(async() =>
                {
                    Assert.IsTrue(await server.SendAsync(payload));
                }));
            }

            Assert.IsTrue(Task.WhenAll(taskList).Wait(1000));
        }
コード例 #5
0
        private static void ResetSockets(out PacketSocket server, out PacketSocket client)
        {
            const int Port = 123;

            TaskCompletionSource <TcpClient> serverTask = new();

            var actionBlock = new ActionBlock <TcpClient>(tcp =>
            {
                serverTask.SetResult(tcp);
            });

            using TcpClientListener listener = new();
            listener.ConnectingClientBlock.LinkTo(actionBlock);
            listener.StartListeningForConnections(Port);

            var tcpClient = new TcpClient("localhost", Port);

            client = new PacketSocket(tcpClient);
            server = new PacketSocket(serverTask.Task.Result);

            Assert.IsTrue(client.IsConnected);
            Assert.IsTrue(server.IsConnected);
        }
コード例 #6
0
        public void TestBasicFunctionality()
        {
            const int PORT = 1234;

            EndpointManager endpointManager = new();

            BufferBlock <TcpClient> block = new();

            block.LinkTo(endpointManager.IncomingClientBlock);

            using TcpClientListener listener = new TcpClientListener();
            listener.StartListeningForConnections(PORT);
            listener.ConnectingClientBlock.LinkTo(endpointManager.IncomingClientBlock);

            //
            // add unconnected client
            // add client -> multiple clients
            // disconnect client (extern)
            // disconnect client (local, null)
            // disconnect client (local, unregistered)
            // disconnect client (local)
            // add 2 clients
            // send message via client 1
            // send message via client 2
            //

            AsyncBarrier barrier = null;

            EndpointEventType expectedType = new();

            TcpClient clientUnconnected      = new();
            TcpClient client1                = new();
            TcpClient client2                = new();
            TcpClient client3                = new();
            TcpClient clientRemoteDisconnect = new();
            TcpClient clientLocalDisconnect  = new();
            IEndpoint ep = new Endpoint(new PacketSocket(clientUnconnected));
            IEndpoint localDisconnectEp = null;
            bool      local             = false;

            bool remoteDisconnect = false;

            List <IEndpoint> epList = new List <IEndpoint>();

            SemaphoreSlim sem = new(1);

            endpointManager.EndpointConnectedHandler = async ep =>
            {
                Assert.IsTrue(expectedType == EndpointEventType.Connect);

                await sem.WaitAsync();

                epList.Add(ep);

                if (local)
                {
                    localDisconnectEp = ep;
                }

                TestUtils.AssertTask(barrier.SignalAsync());
                sem.Release();
            };
            endpointManager.EndpointDisconnectedHandler = async(ep, remote) =>
            {
                Assert.AreEqual(remoteDisconnect, remote);
                Assert.IsTrue(expectedType == EndpointEventType.Disconnect);

                await sem.WaitAsync();

                Assert.IsTrue(epList.Remove(ep));

                TestUtils.AssertTask(barrier.SignalAsync());
                sem.Release();
            };

            expectedType = EndpointEventType.Connect;
            barrier      = new(4, false);

            // add unconnected client
            TestUtils.AssertTask(block.SendAsync(clientUnconnected));

            var tasks = new List <Task>();

            // add client -> multiple clients
            tasks.Add(Task.Run(() => client1.Connect("localhost", PORT)));
            tasks.Add(Task.Run(() => client2.Connect("localhost", PORT)));
            tasks.Add(Task.Run(() => client3.Connect("localhost", PORT)));
            tasks.Add(Task.Run(() => clientRemoteDisconnect.Connect("localhost", PORT)));
            TestUtils.AssertTask(barrier.WaitAsync(), 3000);

            local   = true;
            barrier = new(1, false);
            tasks.Add(Task.Run(() => clientLocalDisconnect.Connect("localhost", PORT)));
            TestUtils.AssertTask(barrier.WaitAsync(), 3000);
            local = false;

            CollectionAssert.Contains(epList, localDisconnectEp);
            CollectionAssert.Contains(endpointManager.ConnectedEndpoints, localDisconnectEp);
            Assert.AreEqual(5, endpointManager.ConnectedEndpoints.Count);
            CollectionAssert.AreEquivalent(epList, endpointManager.ConnectedEndpoints);
            Assert.IsNotNull(localDisconnectEp);

            // disconnect client (remote)
            expectedType     = EndpointEventType.Disconnect;
            remoteDisconnect = true;
            barrier          = new(1, false);
            clientRemoteDisconnect.Close();
            TestUtils.AssertTask(barrier.WaitAsync());
            Assert.AreEqual(4, endpointManager.ConnectedEndpoints.Count);
            Assert.AreEqual(4, epList.Count);
            CollectionAssert.AreEquivalent(epList, endpointManager.ConnectedEndpoints);
            CollectionAssert.Contains(epList, localDisconnectEp);
            CollectionAssert.Contains(endpointManager.ConnectedEndpoints, localDisconnectEp);

            // disconnect client (local, null)
            remoteDisconnect = false;
            TestUtils.AssertException <ArgumentNullException>(endpointManager.DisconnectEndpointAsync(null));

            // disconnect client (local, unregistered)
            TestUtils.AssertException <ArgumentException>(endpointManager.DisconnectEndpointAsync(ep));

            CollectionAssert.AreEquivalent(epList, endpointManager.ConnectedEndpoints);
            // disconnect client (local)
            barrier = new(1, false);
            CollectionAssert.Contains(endpointManager.ConnectedEndpoints, localDisconnectEp);
            TestUtils.AssertTask(endpointManager.DisconnectEndpointAsync(localDisconnectEp));
            TestUtils.AssertTask(barrier.WaitAsync());
            CollectionAssert.AreEquivalent(epList, endpointManager.ConnectedEndpoints);
            CollectionAssert.DoesNotContain(endpointManager.ConnectedEndpoints, localDisconnectEp);

            barrier = new(1, false);

            byte[] buffer = Encoding.ASCII.GetBytes("Hello World!");

            ActionBlock <RawMessage> aB = new(m =>
            {
                CollectionAssert.AreEqual(buffer, m.Data);
                _ = barrier.SignalAsync();
            });

            foreach (var e in endpointManager.ConnectedEndpoints)
            {
                Assert.IsTrue(e.Socket.IsConnected);
            }
            Assert.IsTrue(client1.Connected);

            PacketSocket socket1 = new PacketSocket(client1);


            Assert.IsTrue(socket1.IsReceiving);

            Assert.IsTrue(socket1.IsConnected);


            endpointManager.RawMessageBlock.LinkTo(aB);

            Assert.IsTrue(TestUtils.AssertTask(socket1.SendAsync(buffer)));
            TestUtils.AssertTask(barrier.WaitAsync());
        }
コード例 #7
0
        public void TestLocalRemoteDisconnect()
        {
            /*
             * ensure socket disconnect event is called properly
             *
             * pre: server <-> client: connected
             * - disconnect client
             * -> server: remote disconnect
             * -> client: local disconnect
             */

            TaskCompletionSource tcs = new();

            const int PORT = 1634;

            using TcpClientListener listener = new();
            listener.StartListeningForConnections(PORT);
            PacketSocket            server = null, client;
            ActionBlock <TcpClient> aB = new(c =>
            {
                server = new PacketSocket(c);
                tcs.SetResult();
            });

            listener.ConnectingClientBlock.LinkTo(aB);

            client = new PacketSocket();
            TestUtils.AssertTask(client.ConnectAsync("localhost", PORT), 3000);

            TestUtils.AssertTask(tcs.Task);

            Assert.IsTrue(server.IsConnected);
            Assert.IsTrue(client.IsConnected);
            Assert.IsTrue(server.IsReceiving);
            Assert.IsTrue(client.IsReceiving);

            TaskCompletionSource <bool> serverDisconnected = new();
            TaskCompletionSource <bool> clientDisconnected = new();

            bool onceServer = false;
            bool onceClient = false;

            EventHandler <DisconnectedArgs> serverDisconnect = (sender, e) =>
            {
                Assert.IsFalse(onceServer);
                onceServer = true;
                serverDisconnected.SetResult(e.RemoteDisconnect);
            };
            EventHandler <DisconnectedArgs> clientDisconnect = (sender, e) =>
            {
                Assert.IsFalse(onceClient);
                onceClient = true;
                clientDisconnected.SetResult(e.RemoteDisconnect);
            };

            client.Disconnected += clientDisconnect;
            server.Disconnected += serverDisconnect;

            TestUtils.AssertTask(client.DisconnectAsync());

            Assert.IsFalse(client.IsConnected);

            TestUtils.AssertTask(clientDisconnected.Task);
            TestUtils.AssertTask(serverDisconnected.Task);

            Assert.IsFalse(server.IsConnected);

            Assert.IsFalse(clientDisconnected.Task.Result, "socket falsely detected remote disconnect");
            Assert.IsTrue(serverDisconnected.Task.Result, "socket didn't detect remote disconnect");

            client.Disconnected -= clientDisconnect;
            server.Disconnected -= serverDisconnect;
        }