Skip to content

Instantly share code, notes, and snippets.

@antonfirsov
Created October 16, 2020 14:40
Show Gist options
  • Save antonfirsov/9bcd49ea956644cc9069e5d5a00ee2e6 to your computer and use it in GitHub Desktop.
Save antonfirsov/9bcd49ea956644cc9069e5d5a00ee2e6 to your computer and use it in GitHub Desktop.
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace HangSockets
{
class Program
{
static async Task Main(string[] args)
{
await TestSendReceive();
}
private static async Task TestSendReceive()
{
int msDelay = 100;
(Socket socket1, Socket socket2) = CreateConnectedSocketPair(true);
using (socket2)
{
Task socketOperation = Task.Run(() => socket1.Receive(new byte[1]));
// 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(5000, cts.Token);
Task firstFinished = await Task.WhenAny(disposeTask, socketOperation, timeoutTask);
if (firstFinished == timeoutTask)
{
throw new Exception("Timeout!");
}
cts.Cancel();
await disposeTask;
try
{
await socketOperation;
}
catch (SocketException se)
{
Console.WriteLine(se.SocketErrorCode.ToString());
}
catch (ObjectDisposedException)
{
Console.WriteLine("ObjectDisposedException!");
}
}
static (Socket client, Socket server) CreateConnectedSocketPair(bool ipv6 = false, bool dualModeClient = false)
{
IPAddress serverAddress = ipv6 ? IPAddress.IPv6Loopback : IPAddress.Loopback;
using Socket listener = new Socket(serverAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(serverAddress, 0));
listener.Listen(1);
IPEndPoint connectTo = (IPEndPoint)listener.LocalEndPoint;
if (dualModeClient) connectTo = new IPEndPoint(connectTo.Address.MapToIPv6(), connectTo.Port);
Socket client = new Socket(connectTo.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
if (dualModeClient) client.DualMode = true;
client.Connect(connectTo);
Socket server = listener.Accept();
return (client, server);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment