Exemple #1
0
        public async Task SliceBuffers_Success()
        {
            if (!SupportsSendFileSlicing)
            {
                return;                           // The overloads under test only support sending byte[] without offset and length
            }
            Random rnd = new Random(0);

            ArraySegment <byte> preBuffer  = new ArraySegment <byte>(new byte[100], 25, 50);
            ArraySegment <byte> postBuffer = new ArraySegment <byte>(new byte[100], 25, 50);

            rnd.NextBytes(preBuffer);
            rnd.NextBytes(postBuffer);

            byte[] expected         = preBuffer.ToArray().Concat(postBuffer.ToArray()).ToArray();
            uint   expectedChecksum = Fletcher32.Checksum(expected, 0, expected.Length);

            (Socket client, Socket server) = SocketTestExtensions.CreateConnectedSocketPair();

            using (client)
                using (server)
                {
                    await SendFileAsync(client, null, preBuffer, postBuffer, TransmitFileOptions.UseDefaultWorkerThread);

                    Fletcher32 receivedChecksum = new Fletcher32();
                    byte[]     receiveBuffer    = new byte[expected.Length];
                    int        receivedBytes;
                    int        totalReceived = 0;
                    while (totalReceived < expected.Length && (receivedBytes = server.Receive(receiveBuffer)) != 0)
                    {
                        totalReceived += receivedBytes;
                        receivedChecksum.Add(receiveBuffer, 0, receivedBytes);
                    }
                    Assert.Equal(expected.Length, totalReceived);
                    Assert.Equal(expectedChecksum, receivedChecksum.Sum);
                }
        }
Exemple #2
0
        private static void SendToRecvFromAsync_Datagram_UDP(IPAddress leftAddress, IPAddress rightAddress)
        {
            const int DatagramSize    = 256;
            const int DatagramsToSend = 256;
            const int AckTimeout      = 1000;
            const int TestTimeout     = 30000;

            var left          = new Socket(leftAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            var leftEventArgs = new SocketAsyncEventArgs();

            left.BindToAnonymousPort(leftAddress);

            var right          = new Socket(rightAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            var rightEventArgs = new SocketAsyncEventArgs();

            right.BindToAnonymousPort(rightAddress);

            var leftEndpoint  = (IPEndPoint)left.LocalEndPoint;
            var rightEndpoint = (IPEndPoint)right.LocalEndPoint;

            var receiverAck = new ManualResetEventSlim();
            var senderAck   = new ManualResetEventSlim();

            EndPoint receiveRemote     = leftEndpoint.Create(leftEndpoint.Serialize());
            var      receiverFinished  = new TaskCompletionSource <bool>();
            var      receivedChecksums = new uint?[DatagramsToSend];
            var      receiveBuffer     = new byte[DatagramSize];
            int      receivedDatagrams = -1;

            Action <int, EndPoint> receiveHandler = null;

            receiveHandler = (received, remote) =>
            {
                if (receivedDatagrams != -1)
                {
                    Assert.Equal(DatagramSize, received);
                    Assert.Equal(rightEndpoint, remote);

                    int datagramId = (int)receiveBuffer[0];
                    Assert.Null(receivedChecksums[datagramId]);

                    receivedChecksums[datagramId] = Fletcher32.Checksum(receiveBuffer, 0, received);

                    receiverAck.Set();
                    Assert.True(senderAck.Wait(AckTimeout));
                    senderAck.Reset();

                    receivedDatagrams++;
                    if (receivedDatagrams == DatagramsToSend)
                    {
                        left.Dispose();
                        receiverFinished.SetResult(true);
                        return;
                    }
                }
                else
                {
                    receivedDatagrams = 0;
                }

                left.ReceiveFromAsync(leftEventArgs, receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, receiveRemote, receiveHandler);
            };

            receiveHandler(0, null);

            var random        = new Random();
            var sentChecksums = new uint[DatagramsToSend];
            var sendBuffer    = new byte[DatagramSize];
            int sentDatagrams = -1;

            Action <int> sendHandler = null;

            sendHandler = sent =>
            {
                if (sentDatagrams != -1)
                {
                    Assert.True(receiverAck.Wait(AckTimeout));
                    receiverAck.Reset();
                    senderAck.Set();

                    Assert.Equal(DatagramSize, sent);
                    sentChecksums[sentDatagrams] = Fletcher32.Checksum(sendBuffer, 0, sent);

                    sentDatagrams++;
                    if (sentDatagrams == DatagramsToSend)
                    {
                        right.Dispose();
                        return;
                    }
                }
                else
                {
                    sentDatagrams = 0;
                }

                random.NextBytes(sendBuffer);
                sendBuffer[0] = (byte)sentDatagrams;
                right.SendToAsync(rightEventArgs, sendBuffer, 0, sendBuffer.Length, SocketFlags.None, leftEndpoint, sendHandler);
            };

            sendHandler(0);

            Assert.True(receiverFinished.Task.Wait(TestTimeout));
            for (int i = 0; i < DatagramsToSend; i++)
            {
                Assert.NotNull(receivedChecksums[i]);
                Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]);
            }
        }
Exemple #3
0
        private static void SendToRecvFromAsync_UdpClient_Datagram_UDP(IPAddress leftAddress, IPAddress rightAddress)
        {
            const int DatagramSize    = 256;
            const int DatagramsToSend = 256;
            const int AckTimeout      = 1000;
            const int TestTimeout     = 30000;

            var left  = new UdpClient(new IPEndPoint(leftAddress, 0));
            var right = new UdpClient(new IPEndPoint(rightAddress, 0));

            var leftEndpoint  = (IPEndPoint)left.Client.LocalEndPoint;
            var rightEndpoint = (IPEndPoint)right.Client.LocalEndPoint;

            var receiverAck = new ManualResetEventSlim();
            var senderAck   = new ManualResetEventSlim();

            var receivedChecksums = new uint?[DatagramsToSend];
            int receivedDatagrams = 0;

            Task receiverTask = Task.Run(async() =>
            {
                for (; receivedDatagrams < DatagramsToSend; receivedDatagrams++)
                {
                    UdpReceiveResult result = await left.ReceiveAsync();

                    receiverAck.Set();
                    Assert.True(senderAck.Wait(AckTimeout));
                    senderAck.Reset();

                    Assert.Equal(DatagramSize, result.Buffer.Length);
                    Assert.Equal(rightEndpoint, result.RemoteEndPoint);

                    int datagramId = (int)result.Buffer[0];
                    Assert.Null(receivedChecksums[datagramId]);

                    receivedChecksums[datagramId] = Fletcher32.Checksum(result.Buffer, 0, result.Buffer.Length);
                }
            });

            var sentChecksums = new uint[DatagramsToSend];
            int sentDatagrams = 0;

            Task senderTask = Task.Run(async() =>
            {
                var random     = new Random();
                var sendBuffer = new byte[DatagramSize];

                for (; sentDatagrams < DatagramsToSend; sentDatagrams++)
                {
                    random.NextBytes(sendBuffer);
                    sendBuffer[0] = (byte)sentDatagrams;

                    int sent = await right.SendAsync(sendBuffer, DatagramSize, leftEndpoint);

                    Assert.True(receiverAck.Wait(AckTimeout));
                    receiverAck.Reset();
                    senderAck.Set();

                    Assert.Equal(DatagramSize, sent);
                    sentChecksums[sentDatagrams] = Fletcher32.Checksum(sendBuffer, 0, sent);
                }
            });

            Assert.True(Task.WaitAll(new[] { receiverTask, senderTask }, TestTimeout));
            for (int i = 0; i < DatagramsToSend; i++)
            {
                Assert.NotNull(receivedChecksums[i]);
                Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]);
            }
        }
Exemple #4
0
        private static void SendToRecvFrom_Datagram_UDP(IPAddress leftAddress, IPAddress rightAddress)
        {
            // TODO #5185: Harden against packet loss
            const int DatagramSize    = 256;
            const int DatagramsToSend = 256;
            const int AckTimeout      = 1000;
            const int TestTimeout     = 30000;

            var left = new Socket(leftAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            left.BindToAnonymousPort(leftAddress);

            var right = new Socket(rightAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            right.BindToAnonymousPort(rightAddress);

            var leftEndpoint  = (IPEndPoint)left.LocalEndPoint;
            var rightEndpoint = (IPEndPoint)right.LocalEndPoint;

            var receiverAck = new ManualResetEventSlim();
            var senderAck   = new ManualResetEventSlim();

            var receivedChecksums = new uint?[DatagramsToSend];
            var leftThread        = new Thread(() =>
            {
                using (left)
                {
                    EndPoint remote = leftEndpoint.Create(leftEndpoint.Serialize());
                    var recvBuffer  = new byte[DatagramSize];
                    for (int i = 0; i < DatagramsToSend; i++)
                    {
                        int received = left.ReceiveFrom(recvBuffer, SocketFlags.None, ref remote);
                        Assert.Equal(DatagramSize, received);
                        Assert.Equal(rightEndpoint, remote);

                        int datagramId = (int)recvBuffer[0];
                        Assert.Null(receivedChecksums[datagramId]);
                        receivedChecksums[datagramId] = Fletcher32.Checksum(recvBuffer, 0, received);

                        receiverAck.Set();
                        Assert.True(senderAck.Wait(AckTimeout));
                        senderAck.Reset();
                    }
                }
            });

            leftThread.Start();

            var sentChecksums = new uint[DatagramsToSend];

            using (right)
            {
                var random     = new Random();
                var sendBuffer = new byte[DatagramSize];
                for (int i = 0; i < DatagramsToSend; i++)
                {
                    random.NextBytes(sendBuffer);
                    sendBuffer[0] = (byte)i;

                    int sent = right.SendTo(sendBuffer, SocketFlags.None, leftEndpoint);

                    Assert.True(receiverAck.Wait(AckTimeout));
                    receiverAck.Reset();
                    senderAck.Set();

                    Assert.Equal(DatagramSize, sent);
                    sentChecksums[i] = Fletcher32.Checksum(sendBuffer, 0, sent);
                }
            }

            Assert.True(leftThread.Join(TestTimeout));
            for (int i = 0; i < DatagramsToSend; i++)
            {
                Assert.NotNull(receivedChecksums[i]);
                Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]);
            }
        }
Exemple #5
0
        public async Task SendToRecvFrom_Datagram_UDP(IPAddress loopbackAddress)
        {
            IPAddress leftAddress = loopbackAddress, rightAddress = loopbackAddress;

            // TODO #5185: Harden against packet loss
            const int DatagramSize    = 256;
            const int DatagramsToSend = 256;
            const int AckTimeout      = 1000;
            const int TestTimeout     = 30000;

            var left = new Socket(leftAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            left.BindToAnonymousPort(leftAddress);

            var right = new Socket(rightAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            right.BindToAnonymousPort(rightAddress);

            var leftEndpoint  = (IPEndPoint)left.LocalEndPoint;
            var rightEndpoint = (IPEndPoint)right.LocalEndPoint;

            var receiverAck = new SemaphoreSlim(0);
            var senderAck   = new SemaphoreSlim(0);

            var  receivedChecksums = new uint?[DatagramsToSend];
            Task leftThread        = Task.Run(async() =>
            {
                using (left)
                {
                    EndPoint remote = leftEndpoint.Create(leftEndpoint.Serialize());
                    var recvBuffer  = new byte[DatagramSize];
                    for (int i = 0; i < DatagramsToSend; i++)
                    {
                        SocketReceiveFromResult result = await ReceiveFromAsync(
                            left, new ArraySegment <byte>(recvBuffer), remote);
                        Assert.Equal(DatagramSize, result.ReceivedBytes);
                        Assert.Equal(rightEndpoint, result.RemoteEndPoint);

                        int datagramId = recvBuffer[0];
                        Assert.Null(receivedChecksums[datagramId]);
                        receivedChecksums[datagramId] = Fletcher32.Checksum(recvBuffer, 0, result.ReceivedBytes);

                        receiverAck.Release();
                        Assert.True(await senderAck.WaitAsync(TestTimeout));
                    }
                }
            });

            var sentChecksums = new uint[DatagramsToSend];

            using (right)
            {
                var random     = new Random();
                var sendBuffer = new byte[DatagramSize];
                for (int i = 0; i < DatagramsToSend; i++)
                {
                    random.NextBytes(sendBuffer);
                    sendBuffer[0] = (byte)i;

                    int sent = await SendToAsync(right, new ArraySegment <byte>(sendBuffer), leftEndpoint);

                    Assert.True(await receiverAck.WaitAsync(AckTimeout));
                    senderAck.Release();

                    Assert.Equal(DatagramSize, sent);
                    sentChecksums[i] = Fletcher32.Checksum(sendBuffer, 0, sent);
                }
            }

            await leftThread;

            for (int i = 0; i < DatagramsToSend; i++)
            {
                Assert.NotNull(receivedChecksums[i]);
                Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]);
            }
        }
        public async Task SendToRecvFromAsync_Datagram_UDP_UdpClient(IPAddress loopbackAddress, bool useMemoryOverload)
        {
            IPAddress leftAddress = loopbackAddress, rightAddress = loopbackAddress;

            const int DatagramSize    = 256;
            const int DatagramsToSend = 256;
            const int AckTimeout      = 20000;
            const int TestTimeout     = 60000;

            using (var left = new UdpClient(new IPEndPoint(leftAddress, 0)))
                using (var right = new UdpClient(new IPEndPoint(rightAddress, 0)))
                {
                    var leftEndpoint  = (IPEndPoint)left.Client.LocalEndPoint;
                    var rightEndpoint = (IPEndPoint)right.Client.LocalEndPoint;

                    var receiverAck = new ManualResetEventSlim();
                    var senderAck   = new ManualResetEventSlim();

                    var receivedChecksums = new uint?[DatagramsToSend];
                    int receivedDatagrams = 0;

                    Task receiverTask = Task.Run(async() =>
                    {
                        for (; receivedDatagrams < DatagramsToSend; receivedDatagrams++)
                        {
                            UdpReceiveResult result = await left.ReceiveAsync();

                            receiverAck.Set();
                            Assert.True(senderAck.Wait(AckTimeout));
                            senderAck.Reset();

                            Assert.Equal(DatagramSize, result.Buffer.Length);
                            Assert.Equal(rightEndpoint, result.RemoteEndPoint);

                            int datagramId = (int)result.Buffer[0];
                            Assert.Null(receivedChecksums[datagramId]);

                            receivedChecksums[datagramId] = Fletcher32.Checksum(result.Buffer, 0, result.Buffer.Length);
                        }
                    });

                    var sentChecksums = new uint[DatagramsToSend];
                    int sentDatagrams = 0;

                    Task senderTask = Task.Run(async() =>
                    {
                        var random     = new Random();
                        var sendBuffer = new byte[DatagramSize];

                        for (; sentDatagrams < DatagramsToSend; sentDatagrams++)
                        {
                            random.NextBytes(sendBuffer);
                            sendBuffer[0] = (byte)sentDatagrams;

                            int sent = useMemoryOverload ? await right.SendAsync(new ReadOnlyMemory <byte>(sendBuffer), leftEndpoint) : await right.SendAsync(sendBuffer, DatagramSize, leftEndpoint);

                            Assert.True(receiverAck.Wait(AckTimeout));
                            receiverAck.Reset();
                            senderAck.Set();

                            Assert.Equal(DatagramSize, sent);
                            sentChecksums[sentDatagrams] = Fletcher32.Checksum(sendBuffer, 0, sent);
                        }
                    });

                    await(new[] { receiverTask, senderTask }).WhenAllOrAnyFailed(TestTimeout);
                    for (int i = 0; i < DatagramsToSend; i++)
                    {
                        Assert.NotNull(receivedChecksums[i]);
                        Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]);
                    }
                }
        }
        public async Task SendToRecvFrom_Datagram_UDP(IPAddress loopbackAddress, bool useClone)
        {
            IPAddress leftAddress = loopbackAddress, rightAddress = loopbackAddress;

            const int DatagramSize       = 256;
            const int DatagramsToSend    = 256;
            const int ReceiverAckTimeout = 5000;
            const int SenderAckTimeout   = 10000;

            using var origLeft  = new Socket(leftAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            using var origRight = new Socket(rightAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            origLeft.BindToAnonymousPort(leftAddress);
            origRight.BindToAnonymousPort(rightAddress);

            using var left  = useClone ? new Socket(origLeft.SafeHandle) : origLeft;
            using var right = useClone ? new Socket(origRight.SafeHandle) : origRight;

            // Force non-blocking mode in ...SyncForceNonBlocking variants of the test:
            ConfigureNonBlocking(left);
            ConfigureNonBlocking(right);

            var leftEndpoint  = (IPEndPoint)left.LocalEndPoint;
            var rightEndpoint = (IPEndPoint)right.LocalEndPoint;

            var receiverAck = new SemaphoreSlim(0);
            var senderAck   = new SemaphoreSlim(0);

            _output.WriteLine($"{DateTime.Now}: Sending data from {rightEndpoint} to {leftEndpoint}");

            var  receivedChecksums = new uint?[DatagramsToSend];
            Task leftThread        = Task.Run(async() =>
            {
                EndPoint remote = leftEndpoint.Create(leftEndpoint.Serialize());
                var recvBuffer  = new byte[DatagramSize];
                for (int i = 0; i < DatagramsToSend; i++)
                {
                    SocketReceiveFromResult result = await ReceiveFromAsync(
                        left, new ArraySegment <byte>(recvBuffer), remote);
                    Assert.Equal(DatagramSize, result.ReceivedBytes);
                    Assert.Equal(rightEndpoint, result.RemoteEndPoint);

                    int datagramId = recvBuffer[0];
                    Assert.Null(receivedChecksums[datagramId]);
                    receivedChecksums[datagramId] = Fletcher32.Checksum(recvBuffer, 0, result.ReceivedBytes);

                    receiverAck.Release();
                    bool gotAck = await senderAck.WaitAsync(SenderAckTimeout);
                    Assert.True(gotAck, $"{DateTime.Now}: Timeout waiting {SenderAckTimeout} for senderAck in iteration {i}");
                }
            });

            var sentChecksums = new uint[DatagramsToSend];

            using (right)
            {
                var random     = new Random();
                var sendBuffer = new byte[DatagramSize];
                for (int i = 0; i < DatagramsToSend; i++)
                {
                    random.NextBytes(sendBuffer);
                    sendBuffer[0] = (byte)i;

                    int sent = await SendToAsync(right, new ArraySegment <byte>(sendBuffer), leftEndpoint);

                    bool gotAck = await receiverAck.WaitAsync(ReceiverAckTimeout);

                    Assert.True(gotAck, $"{DateTime.Now}: Timeout waiting {ReceiverAckTimeout} for receiverAck in iteration {i} after sending {sent}. Receiver is in {leftThread.Status}");
                    senderAck.Release();

                    Assert.Equal(DatagramSize, sent);
                    sentChecksums[i] = Fletcher32.Checksum(sendBuffer, 0, sent);
                }
            }

            await leftThread;

            for (int i = 0; i < DatagramsToSend; i++)
            {
                Assert.NotNull(receivedChecksums[i]);
                Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]);
            }
        }