public void SendRecvAsync_TcpListener_TcpClient(IPAddress listenAt) { const int BytesToSend = 123456; const int ListenBacklog = 1; const int LingerTime = 10; const int TestTimeout = 30000; var listener = new TcpListener(listenAt, 0); listener.Start(ListenBacklog); int bytesReceived = 0; var receivedChecksum = new Fletcher32(); Task serverTask = Task.Run(async () => { using (TcpClient remote = await listener.AcceptTcpClientAsync()) using (NetworkStream stream = remote.GetStream()) { var recvBuffer = new byte[256]; for (;;) { int received = await stream.ReadAsync(recvBuffer, 0, recvBuffer.Length); if (received == 0) { break; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } } }); int bytesSent = 0; var sentChecksum = new Fletcher32(); Task clientTask = Task.Run(async () => { var clientEndpoint = (IPEndPoint)listener.LocalEndpoint; using (var client = new TcpClient(clientEndpoint.AddressFamily)) { await client.ConnectAsync(clientEndpoint.Address, clientEndpoint.Port); using (NetworkStream stream = client.GetStream()) { var random = new Random(); var sendBuffer = new byte[512]; for (int remaining = BytesToSend, sent = 0; remaining > 0; remaining -= sent) { random.NextBytes(sendBuffer); sent = Math.Min(sendBuffer.Length, remaining); await stream.WriteAsync(sendBuffer, 0, sent); bytesSent += sent; sentChecksum.Add(sendBuffer, 0, sent); } client.LingerState = new LingerOption(true, LingerTime); } } }); Assert.True(Task.WaitAll(new[] { serverTask, clientTask }, TestTimeout)); Assert.Equal(bytesSent, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); }
private string CreateFileToSend(int size, bool sendPreAndPostBuffers, out byte[] preBuffer, out byte[] postBuffer, out Fletcher32 checksum) { // Create file to send var random = new Random(); int fileSize = sendPreAndPostBuffers ? size - 512 : size; checksum = new Fletcher32(); preBuffer = null; if (sendPreAndPostBuffers) { preBuffer = new byte[256]; random.NextBytes(preBuffer); checksum.Add(preBuffer, 0, preBuffer.Length); } byte[] fileBuffer = new byte[fileSize]; random.NextBytes(fileBuffer); string path = Path.GetTempFileName(); File.WriteAllBytes(path, fileBuffer); checksum.Add(fileBuffer, 0, fileBuffer.Length); postBuffer = null; if (sendPreAndPostBuffers) { postBuffer = new byte[256]; random.NextBytes(postBuffer); checksum.Add(postBuffer, 0, postBuffer.Length); } return path; }
private TempFile CreateFileToSend(int size, bool sendPreAndPostBuffers, out byte[] preBuffer, out byte[] postBuffer, out Fletcher32 checksum) { // Create file to send var random = new Random(); int fileSize = sendPreAndPostBuffers ? size - 512 : size; checksum = new Fletcher32(); preBuffer = null; if (sendPreAndPostBuffers) { preBuffer = new byte[256]; random.NextBytes(preBuffer); checksum.Add(preBuffer, 0, preBuffer.Length); } byte[] fileBuffer = new byte[fileSize]; random.NextBytes(fileBuffer); var tempFile = TempFile.Create(fileBuffer); checksum.Add(fileBuffer, 0, fileBuffer.Length); postBuffer = null; if (sendPreAndPostBuffers) { postBuffer = new byte[256]; random.NextBytes(postBuffer); checksum.Add(postBuffer, 0, postBuffer.Length); } return(tempFile); }
private string CreateFileToSend(int size, bool sendPreAndPostBuffers, out byte[] preBuffer, out byte[] postBuffer, out Fletcher32 checksum) { // Create file to send var random = new Random(); int fileSize = sendPreAndPostBuffers ? size - 512 : size; checksum = new Fletcher32(); preBuffer = null; if (sendPreAndPostBuffers) { preBuffer = new byte[256]; random.NextBytes(preBuffer); checksum.Add(preBuffer, 0, preBuffer.Length); } byte[] fileBuffer = new byte[fileSize]; random.NextBytes(fileBuffer); string path = Path.GetTempFileName(); File.WriteAllBytes(path, fileBuffer); checksum.Add(fileBuffer, 0, fileBuffer.Length); postBuffer = null; if (sendPreAndPostBuffers) { postBuffer = new byte[256]; random.NextBytes(postBuffer); checksum.Add(postBuffer, 0, postBuffer.Length); } return(path); }
public void SendFile_APM(IPAddress listenAt, bool sendPreAndPostBuffers, int bytesToSend) { const int ListenBacklog = 1, TestTimeout = 30000; // Create file to send byte[] preBuffer, postBuffer; Fletcher32 sentChecksum; string filename = CreateFileToSend(bytesToSend, sendPreAndPostBuffers, out preBuffer, out postBuffer, out sentChecksum); // Start server using (var listener = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { listener.BindToAnonymousPort(listenAt); listener.Listen(ListenBacklog); int bytesReceived = 0; var receivedChecksum = new Fletcher32(); Task serverTask = Task.Run(async() => { using (var serverStream = new NetworkStream(await listener.AcceptAsync(), ownsSocket: true)) { var buffer = new byte[256]; int bytesRead; while ((bytesRead = await serverStream.ReadAsync(buffer, 0, buffer.Length)) != 0) { bytesReceived += bytesRead; receivedChecksum.Add(buffer, 0, bytesRead); } } }); Task clientTask = Task.Run(async() => { using (var client = new Socket(listener.LocalEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { await client.ConnectAsync(listener.LocalEndPoint); await Task.Factory.FromAsync( (callback, state) => client.BeginSendFile(filename, preBuffer, postBuffer, TransmitFileOptions.UseDefaultWorkerThread, callback, state), iar => client.EndSendFile(iar), null); client.Shutdown(SocketShutdown.Send); } }); // Wait for the tasks to complete Task <Task> firstCompleted = Task.WhenAny(serverTask, clientTask); Assert.True(firstCompleted.Wait(TestTimeout), "Neither client nor server task completed within allowed time"); firstCompleted.Result.GetAwaiter().GetResult(); Assert.True(Task.WaitAll(new[] { serverTask, clientTask }, TestTimeout), $"Tasks didn't complete within allowed time. Server:{serverTask.Status} Client:{clientTask.Status}"); // Validate the results Assert.Equal(bytesToSend, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); } // Clean up the file we created File.Delete(filename); }
public async Task SendRecv_Stream_TCP_LargeMultiBufferSends(IPAddress listenAt) { using (var listener = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) using (var client = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { listener.BindToAnonymousPort(listenAt); listener.Listen(1); Task <Socket> acceptTask = AcceptAsync(listener); await client.ConnectAsync(listener.LocalEndPoint); using (Socket server = await acceptTask) { var sentChecksum = new Fletcher32(); var rand = new Random(); int bytesToSend = 0; var buffers = new List <ArraySegment <byte> >(); const int NumBuffers = 5; for (int i = 0; i < NumBuffers; i++) { var sendBuffer = new byte[12345678]; rand.NextBytes(sendBuffer); bytesToSend += sendBuffer.Length - i; // trim off a few bytes to test offset/count sentChecksum.Add(sendBuffer, i, sendBuffer.Length - i); buffers.Add(new ArraySegment <byte>(sendBuffer, i, sendBuffer.Length - i)); } Task <int> sendTask = SendAsync(client, buffers); var receivedChecksum = new Fletcher32(); int bytesReceived = 0; byte[] recvBuffer = new byte[1024]; while (bytesReceived < bytesToSend) { int received = await ReceiveAsync(server, new ArraySegment <byte>(recvBuffer)); if (received <= 0) { break; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } Assert.Equal(bytesToSend, await sendTask); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); } } }
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); } }
private static void SendRecv_Stream_TCP(IPAddress listenAt, bool useMultipleBuffers) { const int BytesToSend = 123456; const int ListenBacklog = 1; const int LingerTime = 10; const int TestTimeout = 30000; var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp); server.BindToAnonymousPort(listenAt); server.Listen(ListenBacklog); int bytesReceived = 0; var receivedChecksum = new Fletcher32(); var serverThread = new Thread(() => { using (server) { Socket remote = server.Accept(); Assert.NotNull(remote); using (remote) { if (!useMultipleBuffers) { var recvBuffer = new byte[256]; for (;;) { int received = remote.Receive(recvBuffer, 0, recvBuffer.Length, SocketFlags.None); if (received == 0) { break; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } } else { var recvBuffers = new List <ArraySegment <byte> > { new ArraySegment <byte>(new byte[123]), new ArraySegment <byte>(new byte[256], 2, 100), new ArraySegment <byte>(new byte[1], 0, 0), new ArraySegment <byte>(new byte[64], 9, 33) }; for (;;) { int received = remote.Receive(recvBuffers, SocketFlags.None); if (received == 0) { break; } bytesReceived += received; for (int i = 0, remaining = received; i < recvBuffers.Count && remaining > 0; i++) { ArraySegment <byte> buffer = recvBuffers[i]; int toAdd = Math.Min(buffer.Count, remaining); receivedChecksum.Add(buffer.Array, buffer.Offset, toAdd); remaining -= toAdd; } } } } } }); serverThread.Start(); EndPoint clientEndpoint = server.LocalEndPoint; var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.Connect(clientEndpoint); int bytesSent = 0; var sentChecksum = new Fletcher32(); using (client) { var random = new Random(); if (!useMultipleBuffers) { var sendBuffer = new byte[512]; for (int sent = 0, remaining = BytesToSend; remaining > 0; remaining -= sent) { random.NextBytes(sendBuffer); sent = client.Send(sendBuffer, 0, Math.Min(sendBuffer.Length, remaining), SocketFlags.None); bytesSent += sent; sentChecksum.Add(sendBuffer, 0, sent); } } else { var sendBuffers = new List <ArraySegment <byte> > { new ArraySegment <byte>(new byte[23]), new ArraySegment <byte>(new byte[256], 2, 100), new ArraySegment <byte>(new byte[1], 0, 0), new ArraySegment <byte>(new byte[64], 9, 9) }; for (int sent = 0, toSend = BytesToSend; toSend > 0; toSend -= sent) { for (int i = 0; i < sendBuffers.Count; i++) { random.NextBytes(sendBuffers[i].Array); } sent = client.Send(sendBuffers, SocketFlags.None); bytesSent += sent; for (int i = 0, remaining = sent; i < sendBuffers.Count && remaining > 0; i++) { ArraySegment <byte> buffer = sendBuffers[i]; int toAdd = Math.Min(buffer.Count, remaining); sentChecksum.Add(buffer.Array, buffer.Offset, toAdd); remaining -= toAdd; } } } client.LingerState = new LingerOption(true, LingerTime); } Assert.True(serverThread.Join(TestTimeout), "Completed within allowed time"); Assert.Equal(bytesSent, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); }
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]); } }
public void SendRecvPollSync_TcpListener_Socket(IPAddress listenAt, bool pollBeforeOperation) { const int BytesToSend = 123456; const int ListenBacklog = 1; const int TestTimeout = 30000; var listener = new TcpListener(listenAt, 0); listener.Start(ListenBacklog); try { int bytesReceived = 0; var receivedChecksum = new Fletcher32(); Task serverTask = Task.Run(async() => { using (Socket remote = await listener.AcceptSocketAsync()) { var recvBuffer = new byte[256]; while (true) { if (pollBeforeOperation) { Assert.True(remote.Poll(-1, SelectMode.SelectRead), "Read poll before completion should have succeeded"); } int received = remote.Receive(recvBuffer, 0, recvBuffer.Length, SocketFlags.None); if (received == 0) { Assert.True(remote.Poll(0, SelectMode.SelectRead), "Read poll after completion should have succeeded"); break; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } } }); int bytesSent = 0; var sentChecksum = new Fletcher32(); Task clientTask = Task.Run(async() => { var clientEndpoint = (IPEndPoint)listener.LocalEndpoint; using (var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { await client.ConnectAsync(clientEndpoint.Address, clientEndpoint.Port); if (pollBeforeOperation) { Assert.False(client.Poll(TestTimeout, SelectMode.SelectRead), "Expected writer's read poll to fail after timeout"); } var random = new Random(); var sendBuffer = new byte[512]; for (int remaining = BytesToSend, sent = 0; remaining > 0; remaining -= sent) { random.NextBytes(sendBuffer); if (pollBeforeOperation) { Assert.True(client.Poll(-1, SelectMode.SelectWrite), "Write poll should have succeeded"); } sent = client.Send(sendBuffer, 0, Math.Min(sendBuffer.Length, remaining), SocketFlags.None); bytesSent += sent; sentChecksum.Add(sendBuffer, 0, sent); } } }); Assert.True(Task.WaitAll(new[] { serverTask, clientTask }, TestTimeout), "Wait timed out"); Assert.Equal(bytesSent, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); } finally { listener.Stop(); } }
private void SendFile_Synchronous(IPAddress listenAt, bool sendPreAndPostBuffers) { const int BytesToSend = 123456; const int ListenBacklog = 1; const int LingerTime = 10; const int TestTimeout = 30000; // Create file to send byte[] preBuffer; byte[] postBuffer; Fletcher32 sentChecksum; string filename = CreateFileToSend(BytesToSend, sendPreAndPostBuffers, out preBuffer, out postBuffer, out sentChecksum); // Start server var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp); server.BindToAnonymousPort(listenAt); server.Listen(ListenBacklog); int bytesReceived = 0; var receivedChecksum = new Fletcher32(); var serverThread = new Thread(() => { using (server) { Socket remote = server.Accept(); Assert.NotNull(remote); using (remote) { var recvBuffer = new byte[256]; for (;;) { int received = remote.Receive(recvBuffer, 0, recvBuffer.Length, SocketFlags.None); if (received == 0) { break; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } } } }); serverThread.Start(); // Run client EndPoint clientEndpoint = server.LocalEndPoint; var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.Connect(clientEndpoint); using (client) { client.SendFile(filename, preBuffer, postBuffer, TransmitFileOptions.UseDefaultWorkerThread); client.LingerState = new LingerOption(true, LingerTime); } Assert.True(serverThread.Join(TestTimeout), "Completed within allowed time"); Assert.Equal(BytesToSend, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); // Clean up the file we created File.Delete(filename); }
public void SendFile_Synchronous(IPAddress listenAt, bool sendPreAndPostBuffers, int bytesToSend, bool forceNonBlocking) { const int ListenBacklog = 1; const int TestTimeout = 30000; // Create file to send byte[] preBuffer; byte[] postBuffer; Fletcher32 sentChecksum; string filename = CreateFileToSend(bytesToSend, sendPreAndPostBuffers, out preBuffer, out postBuffer, out sentChecksum); // Start server var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp); server.BindToAnonymousPort(listenAt); server.Listen(ListenBacklog); server.ForceNonBlocking(forceNonBlocking); int bytesReceived = 0; var receivedChecksum = new Fletcher32(); var serverThread = new Thread(() => { using (server) { Socket remote = server.Accept(); Assert.NotNull(remote); remote.ForceNonBlocking(forceNonBlocking); using (remote) { var recvBuffer = new byte[256]; for (; ;) { int received = remote.Receive(recvBuffer, 0, recvBuffer.Length, SocketFlags.None); if (received == 0) { break; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } } } }); serverThread.Start(); // Run client EndPoint clientEndpoint = server.LocalEndPoint; var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.ForceNonBlocking(forceNonBlocking); client.Connect(clientEndpoint); using (client) { client.SendFile(filename, preBuffer, postBuffer, TransmitFileOptions.UseDefaultWorkerThread); client.Shutdown(SocketShutdown.Send); } Assert.True(serverThread.Join(TestTimeout), "Completed within allowed time"); Assert.Equal(bytesToSend, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); // Clean up the file we created File.Delete(filename); }
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]); } }
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]); } }
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]); } }
private static void SendRecv_Stream_TCP(IPAddress listenAt, bool useMultipleBuffers) { const int BytesToSend = 123456; const int ListenBacklog = 1; const int LingerTime = 10; const int TestTimeout = 30000; var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp); server.BindToAnonymousPort(listenAt); server.Listen(ListenBacklog); int bytesReceived = 0; var receivedChecksum = new Fletcher32(); var serverThread = new Thread(() => { using (server) { Socket remote = server.Accept(); Assert.NotNull(remote); using (remote) { if (!useMultipleBuffers) { var recvBuffer = new byte[256]; for (;;) { int received = remote.Receive(recvBuffer, 0, recvBuffer.Length, SocketFlags.None); if (received == 0) { break; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } } else { var recvBuffers = new List<ArraySegment<byte>> { new ArraySegment<byte>(new byte[123]), new ArraySegment<byte>(new byte[256], 2, 100), new ArraySegment<byte>(new byte[1], 0, 0), new ArraySegment<byte>(new byte[64], 9, 33) }; for (;;) { int received = remote.Receive(recvBuffers, SocketFlags.None); if (received == 0) { break; } bytesReceived += received; for (int i = 0, remaining = received; i < recvBuffers.Count && remaining > 0; i++) { ArraySegment<byte> buffer = recvBuffers[i]; int toAdd = Math.Min(buffer.Count, remaining); receivedChecksum.Add(buffer.Array, buffer.Offset, toAdd); remaining -= toAdd; } } } } } }); serverThread.Start(); EndPoint clientEndpoint = server.LocalEndPoint; var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.Connect(clientEndpoint); int bytesSent = 0; var sentChecksum = new Fletcher32(); using (client) { var random = new Random(); if (!useMultipleBuffers) { var sendBuffer = new byte[512]; for (int sent = 0, remaining = BytesToSend; remaining > 0; remaining -= sent) { random.NextBytes(sendBuffer); sent = client.Send(sendBuffer, 0, Math.Min(sendBuffer.Length, remaining), SocketFlags.None); bytesSent += sent; sentChecksum.Add(sendBuffer, 0, sent); } } else { var sendBuffers = new List<ArraySegment<byte>> { new ArraySegment<byte>(new byte[23]), new ArraySegment<byte>(new byte[256], 2, 100), new ArraySegment<byte>(new byte[1], 0, 0), new ArraySegment<byte>(new byte[64], 9, 9) }; for (int sent = 0, toSend = BytesToSend; toSend > 0; toSend -= sent) { for (int i = 0; i < sendBuffers.Count; i++) { random.NextBytes(sendBuffers[i].Array); } sent = client.Send(sendBuffers, SocketFlags.None); bytesSent += sent; for (int i = 0, remaining = sent; i < sendBuffers.Count && remaining > 0; i++) { ArraySegment<byte> buffer = sendBuffers[i]; int toAdd = Math.Min(buffer.Count, remaining); sentChecksum.Add(buffer.Array, buffer.Offset, toAdd); remaining -= toAdd; } } } client.LingerState = new LingerOption(true, LingerTime); } Assert.True(serverThread.Join(TestTimeout), "Completed within allowed time"); Assert.Equal(bytesSent, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); }
private void SendFile_APM(IPAddress listenAt, bool sendPreAndPostBuffers) { const int BytesToSend = 123456; const int ListenBacklog = 1; const int LingerTime = 10; const int TestTimeout = 30000; // Create file to send byte[] preBuffer; byte[] postBuffer; Fletcher32 sentChecksum; string filename = CreateFileToSend(BytesToSend, sendPreAndPostBuffers, out preBuffer, out postBuffer, out sentChecksum); // Start server var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp); server.BindToAnonymousPort(listenAt); server.Listen(ListenBacklog); var serverFinished = new TaskCompletionSource <bool>(); int bytesReceived = 0; var receivedChecksum = new Fletcher32(); server.AcceptAPM(remote => { Action <int> recvHandler = null; bool first = true; var recvBuffer = new byte[256]; recvHandler = received => { if (!first) { if (received == 0) { remote.Dispose(); server.Dispose(); serverFinished.SetResult(true); return; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } else { first = false; } remote.ReceiveAPM(recvBuffer, 0, recvBuffer.Length, SocketFlags.None, recvHandler); }; recvHandler(0); }); // Run client EndPoint clientEndpoint = server.LocalEndPoint; var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.ConnectAPM(clientEndpoint, () => { client.SendFileAPM(filename, preBuffer, postBuffer, TransmitFileOptions.UseDefaultWorkerThread, () => { client.LingerState = new LingerOption(true, LingerTime); client.Dispose(); }); }); Assert.True(serverFinished.Task.Wait(TestTimeout), "Completed within allowed time"); Assert.Equal(BytesToSend, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); // Clean up the file we created File.Delete(filename); }
public async Task IncludeFile_Success(IPAddress listenAt, bool sendPreAndPostBuffers, int bytesToSend) { const int ListenBacklog = 1; const int TestTimeout = 30000; // Create file to send byte[] preBuffer; byte[] postBuffer; Fletcher32 sentChecksum; using TempFile tempFile = CreateFileToSend(bytesToSend, sendPreAndPostBuffers, out preBuffer, out postBuffer, out sentChecksum); // Start server var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp); server.BindToAnonymousPort(listenAt); Listen(server, ListenBacklog); // Configures NonBlocking behavior int bytesReceived = 0; var receivedChecksum = new Fletcher32(); var serverTask = Task.Run(() => { using (server) { Socket remote = server.Accept(); Assert.NotNull(remote); using (remote) { var recvBuffer = new byte[256]; while (true) { int received = remote.Receive(recvBuffer, 0, recvBuffer.Length, SocketFlags.None); if (received == 0) { break; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } } } }); // Run client EndPoint serverEndpoint = server.LocalEndPoint; using (var client = new Socket(serverEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { await ConnectAsync(client, serverEndpoint); // Configures NonBlocking behavior await SendFileAsync(client, tempFile.Path, preBuffer, postBuffer, TransmitFileOptions.UseDefaultWorkerThread); client.Shutdown(SocketShutdown.Send); } await serverTask.WaitAsync(TimeSpan.FromMilliseconds(TestTimeout)); Assert.Equal(bytesToSend, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); }
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 void SendRecvPollSync_TcpListener_Socket(IPAddress listenAt, bool pollBeforeOperation) { const int BytesToSend = 123456; const int ListenBacklog = 1; const int TestTimeout = 30000; var listener = new TcpListener(listenAt, 0); listener.Start(ListenBacklog); try { int bytesReceived = 0; var receivedChecksum = new Fletcher32(); Task serverTask = Task.Run(async () => { using (Socket remote = await listener.AcceptSocketAsync()) { var recvBuffer = new byte[256]; while (true) { if (pollBeforeOperation) { Assert.True(remote.Poll(-1, SelectMode.SelectRead), "Read poll before completion should have succeeded"); } int received = remote.Receive(recvBuffer, 0, recvBuffer.Length, SocketFlags.None); if (received == 0) { Assert.True(remote.Poll(0, SelectMode.SelectRead), "Read poll after completion should have succeeded"); break; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } } }); int bytesSent = 0; var sentChecksum = new Fletcher32(); Task clientTask = Task.Run(async () => { var clientEndpoint = (IPEndPoint)listener.LocalEndpoint; using (var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { await client.ConnectAsync(clientEndpoint.Address, clientEndpoint.Port); if (pollBeforeOperation) { Assert.False(client.Poll(TestTimeout, SelectMode.SelectRead), "Expected writer's read poll to fail after timeout"); } var random = new Random(); var sendBuffer = new byte[512]; for (int remaining = BytesToSend, sent = 0; remaining > 0; remaining -= sent) { random.NextBytes(sendBuffer); if (pollBeforeOperation) { Assert.True(client.Poll(-1, SelectMode.SelectWrite), "Write poll should have succeeded"); } sent = client.Send(sendBuffer, 0, Math.Min(sendBuffer.Length, remaining), SocketFlags.None); bytesSent += sent; sentChecksum.Add(sendBuffer, 0, sent); } } }); Assert.True(Task.WaitAll(new[] { serverTask, clientTask }, TestTimeout), "Wait timed out"); Assert.Equal(bytesSent, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); } finally { listener.Stop(); } }
public async Task SendRecv_Stream_TCP(IPAddress listenAt, bool useMultipleBuffers) { const int BytesToSend = 123456, ListenBacklog = 1, LingerTime = 1; int bytesReceived = 0, bytesSent = 0; Fletcher32 receivedChecksum = new Fletcher32(), sentChecksum = new Fletcher32(); using (var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { server.BindToAnonymousPort(listenAt); server.Listen(ListenBacklog); Task serverProcessingTask = Task.Run(async() => { using (Socket remote = await AcceptAsync(server)) { if (!useMultipleBuffers) { var recvBuffer = new byte[256]; for (;;) { int received = await ReceiveAsync(remote, new ArraySegment <byte>(recvBuffer)); if (received == 0) { break; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } } else { var recvBuffers = new List <ArraySegment <byte> > { new ArraySegment <byte>(new byte[123]), new ArraySegment <byte>(new byte[256], 2, 100), new ArraySegment <byte>(new byte[1], 0, 0), new ArraySegment <byte>(new byte[64], 9, 33) }; for (;;) { int received = await ReceiveAsync(remote, recvBuffers); if (received == 0) { break; } bytesReceived += received; for (int i = 0, remaining = received; i < recvBuffers.Count && remaining > 0; i++) { ArraySegment <byte> buffer = recvBuffers[i]; int toAdd = Math.Min(buffer.Count, remaining); receivedChecksum.Add(buffer.Array, buffer.Offset, toAdd); remaining -= toAdd; } } } } }); EndPoint clientEndpoint = server.LocalEndPoint; using (var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { await ConnectAsync(client, clientEndpoint); var random = new Random(); if (!useMultipleBuffers) { var sendBuffer = new byte[512]; for (int sent = 0, remaining = BytesToSend; remaining > 0; remaining -= sent) { random.NextBytes(sendBuffer); sent = await SendAsync(client, new ArraySegment <byte>(sendBuffer, 0, Math.Min(sendBuffer.Length, remaining))); bytesSent += sent; sentChecksum.Add(sendBuffer, 0, sent); } } else { var sendBuffers = new List <ArraySegment <byte> > { new ArraySegment <byte>(new byte[23]), new ArraySegment <byte>(new byte[256], 2, 100), new ArraySegment <byte>(new byte[1], 0, 0), new ArraySegment <byte>(new byte[64], 9, 9) }; for (int sent = 0, toSend = BytesToSend; toSend > 0; toSend -= sent) { for (int i = 0; i < sendBuffers.Count; i++) { random.NextBytes(sendBuffers[i].Array); } sent = await SendAsync(client, sendBuffers); bytesSent += sent; for (int i = 0, remaining = sent; i < sendBuffers.Count && remaining > 0; i++) { ArraySegment <byte> buffer = sendBuffers[i]; int toAdd = Math.Min(buffer.Count, remaining); sentChecksum.Add(buffer.Array, buffer.Offset, toAdd); remaining -= toAdd; } } } client.LingerState = new LingerOption(true, LingerTime); client.Shutdown(SocketShutdown.Send); await serverProcessingTask; } Assert.Equal(bytesSent, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); } }
public void SendRecvAsync_Stream_TCP(IPAddress listenAt, bool useMultipleBuffers) { const int BytesToSend = 123456; const int ListenBacklog = 1; const int LingerTime = 60; const int TestTimeout = 30000; var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp); server.BindToAnonymousPort(listenAt); server.Listen(ListenBacklog); var serverFinished = new TaskCompletionSource<bool>(); int bytesReceived = 0; var receivedChecksum = new Fletcher32(); var serverEventArgs = new SocketAsyncEventArgs(); server.AcceptAsync(serverEventArgs, remote => { Action<int> recvHandler = null; bool first = true; if (!useMultipleBuffers) { var recvBuffer = new byte[256]; recvHandler = received => { if (!first) { if (received == 0) { remote.Dispose(); server.Dispose(); serverFinished.SetResult(true); return; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } else { first = false; } remote.ReceiveAsync(serverEventArgs, recvBuffer, 0, recvBuffer.Length, SocketFlags.None, recvHandler); }; } else { var recvBuffers = new List<ArraySegment<byte>> { new ArraySegment<byte>(new byte[123]), new ArraySegment<byte>(new byte[256], 2, 100), new ArraySegment<byte>(new byte[1], 0, 0), new ArraySegment<byte>(new byte[64], 9, 33) }; recvHandler = received => { if (!first) { if (received == 0) { remote.Dispose(); server.Dispose(); serverFinished.SetResult(true); return; } bytesReceived += received; for (int i = 0, remaining = received; i < recvBuffers.Count && remaining > 0; i++) { ArraySegment<byte> buffer = recvBuffers[i]; int toAdd = Math.Min(buffer.Count, remaining); receivedChecksum.Add(buffer.Array, buffer.Offset, toAdd); remaining -= toAdd; } } else { first = false; } remote.ReceiveAsync(serverEventArgs, recvBuffers, SocketFlags.None, recvHandler); }; } recvHandler(0); }); EndPoint clientEndpoint = server.LocalEndPoint; var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); int bytesSent = 0; var sentChecksum = new Fletcher32(); var clientEventArgs = new SocketAsyncEventArgs(); client.ConnectAsync(clientEventArgs, clientEndpoint, () => { Action<int> sendHandler = null; var random = new Random(); var remaining = BytesToSend; bool first = true; if (!useMultipleBuffers) { var sendBuffer = new byte[512]; sendHandler = sent => { if (!first) { bytesSent += sent; sentChecksum.Add(sendBuffer, 0, sent); remaining -= sent; Assert.True(remaining >= 0); if (remaining == 0) { client.LingerState = new LingerOption(true, LingerTime); client.Dispose(); return; } } else { first = false; } random.NextBytes(sendBuffer); client.SendAsync(clientEventArgs, sendBuffer, 0, Math.Min(sendBuffer.Length, remaining), SocketFlags.None, sendHandler); }; } else { var sendBuffers = new List<ArraySegment<byte>> { new ArraySegment<byte>(new byte[23]), new ArraySegment<byte>(new byte[256], 2, 100), new ArraySegment<byte>(new byte[1], 0, 0), new ArraySegment<byte>(new byte[64], 9, 9) }; sendHandler = sent => { if (!first) { bytesSent += sent; for (int i = 0, r = sent; i < sendBuffers.Count && r > 0; i++) { ArraySegment<byte> buffer = sendBuffers[i]; int toAdd = Math.Min(buffer.Count, r); sentChecksum.Add(buffer.Array, buffer.Offset, toAdd); r -= toAdd; } remaining -= sent; if (remaining <= 0) { client.LingerState = new LingerOption(true, LingerTime); client.Dispose(); return; } } else { first = false; } for (int i = 0; i < sendBuffers.Count; i++) { random.NextBytes(sendBuffers[i].Array); } client.SendAsync(clientEventArgs, sendBuffers, SocketFlags.None, sendHandler); }; } sendHandler(0); }); Assert.True(serverFinished.Task.Wait(TestTimeout), "Completed within allowed time"); Assert.Equal(bytesSent, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); }
public async Task SendRecv_Stream_TCP_AlternateBufferAndBufferList(IPAddress listenAt) { const int BytesToSend = 123456; int bytesReceived = 0, bytesSent = 0; Fletcher32 receivedChecksum = new Fletcher32(), sentChecksum = new Fletcher32(); using (var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { server.BindToAnonymousPort(listenAt); server.Listen(1); Task serverProcessingTask = Task.Run(async() => { using (Socket remote = await AcceptAsync(server)) { byte[] recvBuffer1 = new byte[256], recvBuffer2 = new byte[256]; long iter = 0; while (true) { ArraySegment <byte> seg1 = new ArraySegment <byte>(recvBuffer1), seg2 = new ArraySegment <byte>(recvBuffer2); int received; switch (iter++ % 3) { case 0: // single buffer received = await ReceiveAsync(remote, seg1); break; case 1: // buffer list with a single buffer received = await ReceiveAsync(remote, new List <ArraySegment <byte> > { seg1 }); break; default: // buffer list with multiple buffers received = await ReceiveAsync(remote, new List <ArraySegment <byte> > { seg1, seg2 }); break; } if (received == 0) { break; } bytesReceived += received; receivedChecksum.Add(recvBuffer1, 0, Math.Min(received, recvBuffer1.Length)); if (received > recvBuffer1.Length) { receivedChecksum.Add(recvBuffer2, 0, received - recvBuffer1.Length); } } } }); EndPoint clientEndpoint = server.LocalEndPoint; using (var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { await ConnectAsync(client, clientEndpoint); var random = new Random(); byte[] sendBuffer1 = new byte[512], sendBuffer2 = new byte[512]; long iter = 0; for (int sent = 0, remaining = BytesToSend; remaining > 0; remaining -= sent) { random.NextBytes(sendBuffer1); random.NextBytes(sendBuffer2); int amountFromSendBuffer1 = Math.Min(sendBuffer1.Length, remaining); switch (iter++ % 3) { case 0: // single buffer sent = await SendAsync(client, new ArraySegment <byte>(sendBuffer1, 0, amountFromSendBuffer1)); break; case 1: // buffer list with a single buffer sent = await SendAsync(client, new List <ArraySegment <byte> > { new ArraySegment <byte>(sendBuffer1, 0, amountFromSendBuffer1) }); break; default: // buffer list with multiple buffers sent = await SendAsync(client, new List <ArraySegment <byte> > { new ArraySegment <byte>(sendBuffer1, 0, amountFromSendBuffer1), new ArraySegment <byte>(sendBuffer2, 0, Math.Min(sendBuffer2.Length, remaining - amountFromSendBuffer1)), }); break; } bytesSent += sent; sentChecksum.Add(sendBuffer1, 0, Math.Min(sent, sendBuffer1.Length)); if (sent > sendBuffer1.Length) { sentChecksum.Add(sendBuffer2, 0, sent - sendBuffer1.Length); } } client.Shutdown(SocketShutdown.Send); await serverProcessingTask; } Assert.Equal(bytesSent, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); } }
private static void SendRecvAsync_Stream_TCP(IPAddress listenAt, bool useMultipleBuffers) { const int BytesToSend = 123456; const int ListenBacklog = 1; const int LingerTime = 10; const int TestTimeout = 30000; var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp); server.BindToAnonymousPort(listenAt); server.Listen(ListenBacklog); var serverFinished = new TaskCompletionSource <bool>(); int bytesReceived = 0; var receivedChecksum = new Fletcher32(); var serverEventArgs = new SocketAsyncEventArgs(); server.AcceptAsync(serverEventArgs, remote => { Action <int> recvHandler = null; bool first = true; if (!useMultipleBuffers) { var recvBuffer = new byte[256]; recvHandler = received => { if (!first) { if (received == 0) { remote.Dispose(); server.Dispose(); serverFinished.SetResult(true); return; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } else { first = false; } remote.ReceiveAsync(serverEventArgs, recvBuffer, 0, recvBuffer.Length, SocketFlags.None, recvHandler); }; } else { var recvBuffers = new List <ArraySegment <byte> > { new ArraySegment <byte>(new byte[123]), new ArraySegment <byte>(new byte[256], 2, 100), new ArraySegment <byte>(new byte[1], 0, 0), new ArraySegment <byte>(new byte[64], 9, 33) }; recvHandler = received => { if (!first) { if (received == 0) { remote.Dispose(); server.Dispose(); serverFinished.SetResult(true); return; } bytesReceived += received; for (int i = 0, remaining = received; i < recvBuffers.Count && remaining > 0; i++) { ArraySegment <byte> buffer = recvBuffers[i]; int toAdd = Math.Min(buffer.Count, remaining); receivedChecksum.Add(buffer.Array, buffer.Offset, toAdd); remaining -= toAdd; } } else { first = false; } remote.ReceiveAsync(serverEventArgs, recvBuffers, SocketFlags.None, recvHandler); }; } recvHandler(0); }); EndPoint clientEndpoint = server.LocalEndPoint; var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); int bytesSent = 0; var sentChecksum = new Fletcher32(); var clientEventArgs = new SocketAsyncEventArgs(); client.ConnectAsync(clientEventArgs, clientEndpoint, () => { Action <int> sendHandler = null; var random = new Random(); var remaining = BytesToSend; bool first = true; if (!useMultipleBuffers) { var sendBuffer = new byte[512]; sendHandler = sent => { if (!first) { bytesSent += sent; sentChecksum.Add(sendBuffer, 0, sent); remaining -= sent; Assert.True(remaining >= 0); if (remaining == 0 || sent == 0) { client.LingerState = new LingerOption(true, LingerTime); client.Dispose(); return; } } else { first = false; } random.NextBytes(sendBuffer); client.SendAsync(clientEventArgs, sendBuffer, 0, Math.Min(sendBuffer.Length, remaining), SocketFlags.None, sendHandler); }; } else { var sendBuffers = new List <ArraySegment <byte> > { new ArraySegment <byte>(new byte[23]), new ArraySegment <byte>(new byte[256], 2, 100), new ArraySegment <byte>(new byte[1], 0, 0), new ArraySegment <byte>(new byte[64], 9, 9) }; sendHandler = sent => { if (!first) { bytesSent += sent; for (int i = 0, r = sent; i < sendBuffers.Count && r > 0; i++) { ArraySegment <byte> buffer = sendBuffers[i]; int toAdd = Math.Min(buffer.Count, r); sentChecksum.Add(buffer.Array, buffer.Offset, toAdd); r -= toAdd; } remaining -= sent; if (remaining <= 0 || sent == 0) { client.LingerState = new LingerOption(true, LingerTime); client.Dispose(); return; } } else { first = false; } for (int i = 0; i < sendBuffers.Count; i++) { random.NextBytes(sendBuffers[i].Array); } client.SendAsync(clientEventArgs, sendBuffers, SocketFlags.None, sendHandler); }; } sendHandler(0); }); Assert.True(serverFinished.Task.Wait(TestTimeout)); Assert.Equal(bytesSent, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); }
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]); } }
private static void SendRecvAsync_TcpListener_TcpClient(IPAddress listenAt) { const int BytesToSend = 123456; const int ListenBacklog = 1; const int LingerTime = 10; const int TestTimeout = 30000; var listener = new TcpListener(listenAt, 0); listener.Start(ListenBacklog); int bytesReceived = 0; var receivedChecksum = new Fletcher32(); Task serverTask = Task.Run(async() => { using (TcpClient remote = await listener.AcceptTcpClientAsync()) using (NetworkStream stream = remote.GetStream()) { var recvBuffer = new byte[256]; for (;;) { int received = await stream.ReadAsync(recvBuffer, 0, recvBuffer.Length); if (received == 0) { break; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } } }); int bytesSent = 0; var sentChecksum = new Fletcher32(); Task clientTask = Task.Run(async() => { var clientEndpoint = (IPEndPoint)listener.LocalEndpoint; using (var client = new TcpClient(clientEndpoint.AddressFamily)) { await client.ConnectAsync(clientEndpoint.Address, clientEndpoint.Port); using (NetworkStream stream = client.GetStream()) { var random = new Random(); var sendBuffer = new byte[512]; for (int remaining = BytesToSend, sent = 0; remaining > 0; remaining -= sent) { random.NextBytes(sendBuffer); sent = Math.Min(sendBuffer.Length, remaining); await stream.WriteAsync(sendBuffer, 0, sent); bytesSent += sent; sentChecksum.Add(sendBuffer, 0, sent); } client.LingerState = new LingerOption(true, LingerTime); } } }); Assert.True(Task.WaitAll(new[] { serverTask, clientTask }, TestTimeout)); Assert.Equal(bytesSent, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); }
private void SendFile_APM(IPAddress listenAt, bool sendPreAndPostBuffers) { const int BytesToSend = 123456; const int ListenBacklog = 1; const int LingerTime = 10; const int TestTimeout = 30000; // Create file to send byte[] preBuffer; byte[] postBuffer; Fletcher32 sentChecksum; string filename = CreateFileToSend(BytesToSend, sendPreAndPostBuffers, out preBuffer, out postBuffer, out sentChecksum); // Start server var server = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp); server.BindToAnonymousPort(listenAt); server.Listen(ListenBacklog); var serverFinished = new TaskCompletionSource<bool>(); int bytesReceived = 0; var receivedChecksum = new Fletcher32(); server.AcceptAPM(remote => { Action<int> recvHandler = null; bool first = true; var recvBuffer = new byte[256]; recvHandler = received => { if (!first) { if (received == 0) { remote.Dispose(); server.Dispose(); serverFinished.SetResult(true); return; } bytesReceived += received; receivedChecksum.Add(recvBuffer, 0, received); } else { first = false; } remote.ReceiveAPM(recvBuffer, 0, recvBuffer.Length, SocketFlags.None, recvHandler); }; recvHandler(0); }); // Run client EndPoint clientEndpoint = server.LocalEndPoint; var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.ConnectAPM(clientEndpoint, () => { client.SendFileAPM(filename, preBuffer, postBuffer, TransmitFileOptions.UseDefaultWorkerThread, () => { client.LingerState = new LingerOption(true, LingerTime); client.Dispose(); }); }); Assert.True(serverFinished.Task.Wait(TestTimeout), "Completed within allowed time"); Assert.Equal(BytesToSend, bytesReceived); Assert.Equal(sentChecksum.Sum, receivedChecksum.Sum); // Clean up the file we created File.Delete(filename); }