public async Task ReceiveSent_TCP_Success(bool ipv6) { if (ipv6 && PlatformDetection.IsOSX) { // [ActiveIssue("https://github.com/dotnet/runtime/issues/47335")] // accept() will create a (seemingly) DualMode socket on Mac, // but since recvmsg() does not work with DualMode on that OS, we throw PNSE CheckDualModeReceiveSupport(). // Weirdly, the flag is readable, but an attempt to write it leads to EINVAL. // The best option seems to be to skip this test for the Mac+IPV6 case return; } (Socket sender, Socket receiver) = SocketTestExtensions.CreateConnectedSocketPair(ipv6); using (sender) using (receiver) { byte[] sendBuffer = { 1, 2, 3 }; sender.Send(sendBuffer); byte[] receiveBuffer = new byte[3]; var r = await ReceiveMessageFromAsync(receiver, receiveBuffer, sender.LocalEndPoint); Assert.Equal(3, r.ReceivedBytes); AssertExtensions.SequenceEqual(sendBuffer, receiveBuffer); } }
public async Task SendFileAsync_CanceledDuringOperation_Throws(bool ipv6) { const int CancelAfter = 200; // ms const int NumOfSends = 100; const int SendBufferSize = 1024; (Socket client, Socket server) = SocketTestExtensions.CreateConnectedSocketPair(ipv6); byte[] buffer = new byte[1024 * 64]; using (client) using (server) { client.SendBufferSize = SendBufferSize; CancellationTokenSource cts = new CancellationTokenSource(); List <Task> tasks = new List <Task>(); // After flooding the socket with a high number of SendFile tasks, // we assume some of them won't complete before the "CancelAfter" period expires. for (int i = 0; i < NumOfSends; i++) { var task = server.SendFileAsync(null, buffer, ReadOnlyMemory <byte> .Empty, TransmitFileOptions.UseDefaultWorkerThread, cts.Token).AsTask(); tasks.Add(task); } cts.CancelAfter(CancelAfter); // We shall see at least one cancellation amongst all the scheduled sends: await Assert.ThrowsAnyAsync <OperationCanceledException>(() => Task.WhenAll(tasks)); } }
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(); (Socket client, Socket server) = SocketTestExtensions.CreateConnectedSocketPair(); using (client) using (server) { await SendFileAsync(client, null, preBuffer, postBuffer, TransmitFileOptions.UseDefaultWorkerThread); byte[] receiveBuffer = new byte[100]; int receivedBytes = server.Receive(receiveBuffer); Assert.Equal(100, receivedBytes); AssertExtensions.SequenceEqual(expected, receiveBuffer); } }
public void EndReceive_Throws_SocketException() { (Socket a, Socket b) = SocketTestExtensions.CreateConnectedSocketPair(); using (b) { var iar = a.BeginReceive(new byte[1], 0, 1, SocketFlags.None, null, null); a.Dispose(); Assert.Throws <SocketException>(() => a.EndReceive(iar)); } }
public void SetUnsupportedSocketOptionIntArg_DoesNotDisconnectSocket() { (Socket socket1, Socket socket2) = SocketTestExtensions.CreateConnectedSocketPair(); using (socket1) using (socket2) { SocketException se = Assert.Throws <SocketException>(() => socket1.SetSocketOption(SocketOptionLevel.Socket, (SocketOptionName)(-1), optionValue: 1)); Assert.True(se.SocketErrorCode == SocketError.ProtocolOption || se.SocketErrorCode == SocketError.OperationNotSupported, $"SocketError: {se.SocketErrorCode}"); Assert.True(socket1.Connected, "Connected"); } }
public void SetUnsupportedRawSocketOption_DoesNotDisconnectSocket() { (Socket socket1, Socket socket2) = SocketTestExtensions.CreateConnectedSocketPair(); using (socket1) using (socket2) { var optionValue = new byte[4]; SocketException se = Assert.Throws <SocketException>(() => socket1.SetRawSocketOption(SOL_SOCKET, -1, optionValue)); Assert.True(se.SocketErrorCode == SocketError.ProtocolOption || se.SocketErrorCode == SocketError.OperationNotSupported, $"SocketError: {se.SocketErrorCode}"); Assert.True(socket1.Connected, "Connected"); } }
public async Task FileDoesNotExist_ThrowsFileNotFoundException(bool useOverloadWithBuffers) { string doesNotExist = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); (Socket client, Socket server) = SocketTestExtensions.CreateConnectedSocketPair(); using (client) using (server) { if (!useOverloadWithBuffers) { await Assert.ThrowsAsync <FileNotFoundException>(() => SendFileAsync(client, doesNotExist)); } else { await Assert.ThrowsAsync <FileNotFoundException>(() => SendFileAsync(client, doesNotExist, null, null, TransmitFileOptions.UseDefaultWorkerThread)); } } }
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); } }
public async Task SyncSendFileGetsCanceledByDispose() { // We try this a couple of times to deal with a timing race: if the Dispose happens // before the operation is started, the peer won't see a ConnectionReset SocketException and we won't // see a SocketException either. int msDelay = 100; await RetryHelper.ExecuteAsync(async() => { (Socket socket1, Socket socket2) = SocketTestExtensions.CreateConnectedSocketPair(); using (socket2) { Task socketOperation = Task.Run(() => { // Create a large file that will cause SendFile to block until the peer starts reading. string filename = GetTestFilePath(); using (var fs = new FileStream(filename, FileMode.CreateNew, FileAccess.Write)) { fs.SetLength(20 * 1024 * 1024 /* 20MB */); } socket1.SendFile(filename); }); // Wait a little so the operation is started. await Task.Delay(msDelay); msDelay *= 2; Task disposeTask = Task.Run(() => socket1.Dispose()); var cts = new CancellationTokenSource(); Task timeoutTask = Task.Delay(30000, cts.Token); Assert.NotSame(timeoutTask, await Task.WhenAny(disposeTask, socketOperation, timeoutTask)); cts.Cancel(); await disposeTask; SocketError?localSocketError = null; try { await socketOperation; } catch (SocketException se) { localSocketError = se.SocketErrorCode; } catch (ObjectDisposedException) { } Assert.Equal(SocketError.ConnectionAborted, localSocketError); // On OSX, we're unable to unblock the on-going socket operations and // perform an abortive close. if (!PlatformDetection.IsOSXLike) { SocketError?peerSocketError = null; var receiveBuffer = new byte[4096]; while (true) { try { int received = socket2.Receive(receiveBuffer); if (received == 0) { break; } } catch (SocketException se) { peerSocketError = se.SocketErrorCode; break; } } Assert.Equal(SocketError.ConnectionReset, peerSocketError); } } }, maxAttempts : 10); }
public async Task SendFileGetsCanceledByDispose(bool owning) { // Aborting sync operations for non-owning handles is not supported on Unix. if (!owning && UsesSync && !PlatformDetection.IsWindows) { return; } // We try this a couple of times to deal with a timing race: if the Dispose happens // before the operation is started, the peer won't see a ConnectionReset SocketException and we won't // see a SocketException either. int msDelay = 100; await RetryHelper.ExecuteAsync(async() => { (Socket socket1, Socket socket2) = SocketTestExtensions.CreateConnectedSocketPair(); using SafeSocketHandle? owner = ReplaceWithNonOwning(ref socket1, owning); using (socket2) { Task socketOperation = Task.Run(async() => { // Create a large file that will cause SendFile to block until the peer starts reading. using var tempFile = TempFile.Create(); using (var fs = new FileStream(tempFile.Path, FileMode.CreateNew, FileAccess.Write)) { fs.SetLength(20 * 1024 * 1024 /* 20MB */); } await SendFileAsync(socket1, tempFile.Path); }); // Wait a little so the operation is started. await Task.Delay(msDelay); msDelay *= 2; Task disposeTask = Task.Run(() => socket1.Dispose()); await Task.WhenAny(disposeTask, socketOperation).WaitAsync(TimeSpan.FromSeconds(30)); await disposeTask; SocketError?localSocketError = null; try { await socketOperation; } catch (SocketException se) { localSocketError = se.SocketErrorCode; } if (UsesSync) { Assert.Equal(SocketError.ConnectionAborted, localSocketError); } else { Assert.Equal(SocketError.OperationAborted, localSocketError); } owner?.Dispose(); // On OSX, we're unable to unblock the on-going socket operations and // perform an abortive close. if (!(UsesSync && PlatformDetection.IsOSXLike)) { SocketError?peerSocketError = null; var receiveBuffer = new byte[4096]; while (true) { try { int received = socket2.Receive(receiveBuffer); if (received == 0) { break; } } catch (SocketException se) { peerSocketError = se.SocketErrorCode; break; } } Assert.Equal(SocketError.ConnectionReset, peerSocketError); } } }, maxAttempts : 10, retryWhen : e => e is XunitException); }