示例#1
0
        [InlineData(1000)] // yes buffered stream
        public async Task TcpSocketClient_ShouldBeAbleToDisconnectThenReconnect(int bufferSize)
        {
            TcpSocketClient sut = null;

            var port     = PortGranter.GrantPort();
            var listener = new TcpSocketListener();
            await listener.StartListeningAsync(port);

            if (bufferSize != -1)
            {
                sut = new TcpSocketClient(bufferSize);
            }
            else
            {
                sut = new TcpSocketClient();
            }

            await sut.ConnectAsync("127.0.0.1", port);

            await sut.DisconnectAsync();

            await sut.ConnectAsync("127.0.0.1", port);

            await sut.DisconnectAsync();

            await listener.StopListeningAsync();
        }
示例#2
0
        public async Task TcpSocketClient_ShouldBeAbleToConnect()
        {
            var port     = PortGranter.GrantPort();
            var listener = new TcpSocketListener();
            await listener.StartListeningAsync(port);

            var sut = new TcpSocketClient();
            await sut.ConnectAsync("127.0.0.1", port);

            await listener.StopListeningAsync();

            // getting here means nothing went boom
            Assert.True(true);
        }
示例#3
0
        public async Task TcpSocketClient_ShouldSendReceiveData()
        {
            var bytesToSend = new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5 };
            var len         = bytesToSend.Length;
            var port        = PortGranter.GrantPort();

            var listener = new TcpSocketListener();
            await listener.StartListeningAsync(port);

            var tcs = new TaskCompletionSource <bool>();

            listener.ConnectionReceived += async(sender, args) =>
            {
                var bytesReceived = new byte[len];
                await args.SocketClient.ReadStream.ReadAsync(bytesReceived, 0, len);

                var allSame =
                    Enumerable
                    .Zip(bytesToSend,
                         bytesReceived,
                         (s, r) => s == r)
                    .All(b => b);

                tcs.SetResult(allSame);
            };

            var client = new TcpSocketClient();
            await client.ConnectAsync("127.0.0.1", port);

            await client.WriteStream.WriteAsync(bytesToSend, 0, len);

            var ok = await tcs.Task;

            await listener.StopListeningAsync();

            Assert.True(ok);
        }
示例#4
0
        public async Task TcpSocketClient_ShouldSendReceiveDataSimultaneously(int bufferSize)
        {
            var port = PortGranter.GrantPort();

            TcpSocketListener listener = null;
            TcpSocketClient   socket1  = null;

            // get both ends of a connected socket, with or without buffer
            if (bufferSize != -1)
            {
                listener = new TcpSocketListener(bufferSize);
                socket1  = new TcpSocketClient(bufferSize);
            }
            else
            {
                listener = new TcpSocketListener();
                socket1  = new TcpSocketClient();
            }

            var tcs = new TaskCompletionSource <ITcpSocketClient>();

            await listener.StartListeningAsync(port);

            listener.ConnectionReceived += (sender, args) => tcs.SetResult(args.SocketClient);

            await socket1.ConnectAsync("127.0.0.1", port);

            var socket2 = await tcs.Task;
            await listener.StopListeningAsync();

            // socket1 is the socket from the client end
            // socket2 is the socket from the server end

            // for five seconds, send and receive the data
            var sentToSocket1  = new List <byte>();
            var sentToSocket2  = new List <byte>();
            var recvdBySocket1 = new List <byte>();
            var recvdBySocket2 = new List <byte>();

            // send random data and keep track of it
            // also keep track of what is received
            Func <ITcpSocketClient, List <byte>, List <byte>, CancellationToken, Task> sendAndReceive =
                (socket, sent, recvd, token) =>
            {
                var r    = new Random(socket.GetHashCode());
                var send = Task.Run(async() =>
                {
                    var buf = new byte[1000];
                    while (!token.IsCancellationRequested)
                    {
                        r.NextBytes(buf);
                        sent.AddRange(buf);
                        await socket.WriteStream.WriteAsync(buf, 0, buf.Length, token);
                        await socket.WriteStream.FlushAsync(token);
                    }
                });

                var recv = Task.Run(async() =>
                {
                    var buf = new byte[1000];
                    while (!token.IsCancellationRequested)
                    {
                        var len = await socket.ReadStream.ReadAsync(buf, 0, buf.Length, token);
                        recvd.AddRange(buf.Take(len));
                    }
                });

                var innerTcs = new TaskCompletionSource <bool>();
                token.Register(() => innerTcs.SetResult(true));

                return(innerTcs.Task);
            };

            // let the sockets run for 2.5 seconds
            var socketRunners =
                Task.WhenAll(
                    Task.Run(() => sendAndReceive(socket1, sentToSocket2, recvdBySocket1, new CancellationTokenSource(TimeSpan.FromSeconds(2.5)).Token).ContinueWith(t => Debug.WriteLine($"Socket 1 task completed: {t}"))),
                    Task.Run(() => sendAndReceive(socket2, sentToSocket1, recvdBySocket2, new CancellationTokenSource(TimeSpan.FromSeconds(2.5)).Token).ContinueWith(t => Debug.WriteLine($"Socket 2 task completed: {t}")))
                    );

            await socketRunners;

            Debug.WriteLine("Sent to S1:{0}, Recvd by S1:{1}", sentToSocket1.Count, recvdBySocket1.Count);
            Debug.WriteLine("Sent to S2:{0}, Recvd by S2:{1}", sentToSocket2.Count, recvdBySocket2.Count);

            // zip will join up to the lowest index of both lists (must be recvd)
            // it's ok if recvd is shorter than sent because we cancel abruptly,
            // but we want to be sure that everything that was received matches
            // everything that sent, and that we did both send and receive.

            var socket1Errors =
                Enumerable.Zip(recvdBySocket1, sentToSocket1,
                               (r, s) => s == r)
                .Count(b => !b);

            var socket2Errors =
                Enumerable.Zip(recvdBySocket2,
                               sentToSocket2,
                               (r, s) => s == r)
                .Count(b => !b);

            var max = new[] { recvdBySocket1.Count, recvdBySocket2.Count, sentToSocket1.Count, sentToSocket2.Count }.Max();
            Func <List <byte>, int, string> getValueOrStars =
                (bytes, i) => bytes.Count > i ? ((int)bytes[i]).ToString().PadLeft(3, '0') : "***";

            var rows =
                Enumerable.Range(0, max - 1)
                .Select(i =>
            {
                var sTo1 = getValueOrStars(sentToSocket1, i);
                var rBy1 = getValueOrStars(recvdBySocket1, i);
                var sTo2 = getValueOrStars(sentToSocket2, i);
                var rBy2 = getValueOrStars(recvdBySocket2, i);

                return(new { Index = i, SentTo1 = sTo1, ReceivedBy1 = rBy1, SentTo2 = sTo2, ReceivedBy2 = rBy2 });
            })
                .Where(r => (r.SentTo1 != r.ReceivedBy1 && r.ReceivedBy1 != "***") || (r.SentTo2 != r.ReceivedBy2 && r.ReceivedBy2 != "***"))
                .Select(r => $"{r.Index}: \t{r.SentTo1}\t{r.ReceivedBy1}\t{r.SentTo2}\t{r.ReceivedBy2}\t")
                .Take(1000);

            Func <IEnumerable <byte>, string> show = bs => $"[ {String.Join(", ", bs.Take(5).Select(b => (int) b))} ]";

            if (socket1Errors > 0 || socket2Errors > 0)
            {
                Assert.True(socket1Errors == 0,
                            $"Socket1 received {socket1Errors} byte/s that did not match what was sent to it{Environment.NewLine}{String.Join(Environment.NewLine, rows)}");
                Assert.True(socket2Errors == 0,
                            $"Socket2 received {socket2Errors} byte/s that did not match what was sent to it{Environment.NewLine}{String.Join(Environment.NewLine, rows)}");
            }
            // eww, but does the job we need
            Assert.True(recvdBySocket1.Count > 5000, String.Format("Socket 1 received data count was less than 5000 : {0}", recvdBySocket1.Count));
            Assert.True(recvdBySocket2.Count > 5000, String.Format("Socket 2 received data count was less than 5000 : {0}", recvdBySocket2.Count));

            await socket1.DisconnectAsync();

            await socket2.DisconnectAsync();
        }
示例#5
0
        public async Task TcpSocketClient_ShouldSendReceiveDataSimultaneously(int bufferSize)
        {
            var port = PortGranter.GrantPort();

            TcpSocketListener listener = null;
            TcpSocketClient   socket1  = null;

            // get both ends of a connected socket, with or without buffer
            if (bufferSize != -1)
            {
                listener = new TcpSocketListener(bufferSize);
                socket1  = new TcpSocketClient(bufferSize);
            }
            else
            {
                listener = new TcpSocketListener();
                socket1  = new TcpSocketClient();
            }

            var tcs = new TaskCompletionSource <ITcpSocketClient>();

            await listener.StartListeningAsync(port);

            listener.ConnectionReceived += (sender, args) => tcs.SetResult(args.SocketClient);

            await socket1.ConnectAsync("127.0.0.1", port);

            var socket2 = await tcs.Task;
            await listener.StopListeningAsync();

            // socket1 is the socket from the client end
            // socket2 is the socket from the server end

            // for five seconds, send and receive the data
            var sentToSocket1  = new List <byte>();
            var sentToSocket2  = new List <byte>();
            var recvdBySocket1 = new List <byte>();
            var recvdBySocket2 = new List <byte>();

            // send random data and keep track of it
            // also keep track of what is received
            Func <ITcpSocketClient, List <byte>, List <byte>, CancellationToken, Task> sendAndReceive =
                (socket, sent, recvd, token) =>
            {
                var r    = new Random(socket.GetHashCode());
                var send = Task.Run(async() =>
                {
                    var buf = new byte[1000];
                    while (!token.IsCancellationRequested)
                    {
                        r.NextBytes(buf);
                        sent.AddRange(buf);
                        await socket.WriteStream.WriteAsync(buf, 0, buf.Length, token);
                        await socket.WriteStream.FlushAsync();
                    }
                });

                var recv = Task.Run(async() =>
                {
                    var buf = new byte[1000];
                    while (!token.IsCancellationRequested)
                    {
                        await socket.ReadStream.ReadAsync(buf, 0, buf.Length, token);
                        recvd.AddRange(buf);
                    }
                });

                return(Task.WhenAll(send, recv));
            };

            // let the sockets run for 2.5 seconds
            var cts   = new CancellationTokenSource();
            var timer = Task.Run(() => Task.Delay(TimeSpan.FromSeconds(2.5)).ContinueWith(t => cts.Cancel()));

            var socketRunners =
                Task.WhenAll(
                    Task.Run(() => sendAndReceive(socket1, sentToSocket2, recvdBySocket1, cts.Token)),
                    Task.Run(() => sendAndReceive(socket2, sentToSocket1, recvdBySocket2, cts.Token))
                    );

            await timer;
            await socketRunners;

            Debug.WriteLine("Sent to S1:{0}, Recvd by S1:{1}", sentToSocket1.Count, recvdBySocket1.Count);
            Debug.WriteLine("Sent to S2:{0}, Recvd by S2:{1}", sentToSocket2.Count, recvdBySocket2.Count);

            // zip will join up to the lowest index of both lists (must be recvd)
            // it's ok if recvd is shorter than sent because we cancel abruptly,
            // but we want to be sure that everything that was received matches
            // everything that sent, and that we did both send and receive.

            var socket1OK =
                Enumerable.Zip(sentToSocket1,
                               recvdBySocket1,
                               (s, r) => s == r)
                .All(b => b);

            var socket2OK =
                Enumerable.Zip(sentToSocket1,
                               recvdBySocket1,
                               (s, r) => s == r)
                .All(b => b);

            Assert.True(socket1OK, "Socket1 received data did not match what was sent to it");
            Assert.True(socket2OK, "Socket2 received data did not match what was sent to it");

            // eww, but does the job we need
            Assert.True(recvdBySocket1.Count > 5000, String.Format("Socket 1 received data count was less than 5000 : {0}", recvdBySocket1.Count));
            Assert.True(recvdBySocket2.Count > 5000, String.Format("Socket 2 received data count was less than 5000 : {0}", recvdBySocket2.Count));

            await socket1.DisconnectAsync();

            await socket2.DisconnectAsync();
        }