public static void Main(string[] args)
{
Console.WriteLine("Starting...");
X509Certificate2 serverCertificate = new X509Certificate2("certificate.pfx"); // Any valid certificate with private key will work fine.
TcpListener listener = new TcpListener(IPAddress.Any, 4567);
TcpClient client = new TcpClient();
listener.Start();
Task clientConnectTask = client.ConnectAsync(IPAddress.Loopback, 4567);
Task<TcpClient> listenerAcceptTask = listener.AcceptTcpClientAsync();
Task.WaitAll(clientConnectTask, listenerAcceptTask);
TcpClient server = listenerAcceptTask.Result;
SslStream clientStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null, EncryptionPolicy.RequireEncryption);
SslStream serverStream = new SslStream(server.GetStream(), false, null, null, EncryptionPolicy.RequireEncryption);
Task clientAuthenticationTask = clientStream.AuthenticateAsClientAsync(serverCertificate.GetNameInfo(X509NameType.SimpleName, false), null, SslProtocols.Tls12, false);
Task serverAuthenticationTask = serverStream.AuthenticateAsServerAsync(serverCertificate, false, SslProtocols.Tls12, false);
Task.WaitAll(clientAuthenticationTask, serverAuthenticationTask);
byte[] readBuffer = new byte[256];
Task<int> readTask = clientStream.ReadAsync(readBuffer, 0, readBuffer.Length); // Create a pending ReadAsync, which will wait for data that will never come (for testing purposes).
byte[] writeBuffer = new byte[256];
Task writeTask = clientStream.WriteAsync(writeBuffer, 0, writeBuffer.Length); // The main thread actually blocks here (not asychronously waits) on .NET Core making this call.
bool result = Task.WaitAll(new Task[1] { writeTask }, 5000); // This code won't even be reached on .NET Core. Works fine on .NET Framework.
if (result)
{
Console.WriteLine("WriteAsync completed successfully while ReadAsync was pending... nothing locked up.");
}
else
{
Console.WriteLine("WriteAsync failed to complete after 5 seconds.");
}
}