Skip to content

Instantly share code, notes, and snippets.

@halter73
Last active September 18, 2019 22:24
Show Gist options
  • Save halter73/0efed97b495150a633c7b765e24c939a to your computer and use it in GitHub Desktop.
Save halter73/0efed97b495150a633c7b765e24c939a to your computer and use it in GitHub Desktop.
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace SlowClose
{
class Program
{
const int PORT = 8080;
const long SERVER_SEND_CHUNK_SIZE = 4 * 1024;
const long SERVER_SEND_CHUNK_COUNT = 8 * 1024;
const long CLIENT_RECEIVE_CHUNK_SIZE = 64 * 1024;
const double CLIENT_TARGET_BYTES_PER_SECOND = 2 * 1024 * 1024;
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Task.WaitAll(RunServer(), RunClient());
}
static async Task RunServer()
{
using (var listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
listenSocket.Bind(new IPEndPoint(IPAddress.Loopback, PORT));
listenSocket.Listen(0);
using (var socket = await listenSocket.AcceptAsync())
{
var sendChunk = new byte[SERVER_SEND_CHUNK_SIZE].AsMemory();
var receiveChunk = new byte[1].AsMemory();
var readTask = socket.ReceiveAsync(receiveChunk, SocketFlags.None);
for (int i = 0; i < SERVER_SEND_CHUNK_COUNT; i++)
{
//Console.WriteLine("Seinding");
await socket.SendAsync(sendChunk, SocketFlags.None);
//Console.WriteLine("Sent!!!!!");
}
Console.WriteLine("Shuting down socket.");
socket.Shutdown(SocketShutdown.Both);
Console.WriteLine("Shut down socket.");
try
{
var bytesRead = await readTask;
Console.WriteLine("Server read task completed gracefully with {0} bytes read", bytesRead);
}
catch (Exception ex)
{
Console.WriteLine("Server read task completed with error: {0}", ex);
}
}
}
Console.WriteLine("Server sockets disposed");
}
static async Task RunClient()
{
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var totalBytesReceived = 0;
var receiveBuffer = new byte[CLIENT_RECEIVE_CHUNK_SIZE].AsMemory();
await socket.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 8080));
while (totalBytesReceived < SERVER_SEND_CHUNK_SIZE * SERVER_SEND_CHUNK_COUNT)
{
//Console.WriteLine("Receiving");
var received = await socket.ReceiveAsync(receiveBuffer, SocketFlags.None);
//Console.WriteLine("Received: {0}", received);
if (received == 0)
{
Console.WriteLine("Unexpectedly observed end of data");
return;
}
totalBytesReceived += received;
var expectedTimeElapsed = TimeSpan.FromSeconds(totalBytesReceived / CLIENT_TARGET_BYTES_PER_SECOND);
var timeElapsed = stopwatch.Elapsed;
if (timeElapsed + TimeSpan.FromSeconds(1) < expectedTimeElapsed)
{
Console.WriteLine("Delaying {0} seconds after receiving {1} bytes in {2} seconds", expectedTimeElapsed - timeElapsed, totalBytesReceived, timeElapsed);
await Task.Delay(expectedTimeElapsed - timeElapsed);
}
}
}
Console.WriteLine("Read all data");
}
}
}
@halter73
Copy link
Author

halter73 commented Sep 17, 2019

Sample output (no repro 😢):

shalter@f4-linux:~/halter73/SlowClose$ dotnet run
Hello World!
Delaying 00:00:01.0020110 seconds after receiving 2121024 bytes in 00:00:00.0093720 seconds
Delaying 00:00:01.0255896 seconds after receiving 4283712 bytes in 00:00:01.0170434 seconds
Delaying 00:00:01.0300538 seconds after receiving 6446400 bytes in 00:00:02.0438292 seconds
Delaying 00:00:01.0288262 seconds after receiving 8609088 bytes in 00:00:03.0763068 seconds
Delaying 00:00:01.0296704 seconds after receiving 10771776 bytes in 00:00:04.1067126 seconds
Delaying 00:00:01.0283370 seconds after receiving 12934464 bytes in 00:00:05.1392960 seconds
Delaying 00:00:01.0303644 seconds after receiving 15097152 bytes in 00:00:06.1685186 seconds
Delaying 00:00:01.0303645 seconds after receiving 17259840 bytes in 00:00:07.1997685 seconds
Delaying 00:00:01.0303034 seconds after receiving 19422528 bytes in 00:00:08.2310796 seconds
Delaying 00:00:01.0300118 seconds after receiving 21585216 bytes in 00:00:09.2626212 seconds
Delaying 00:00:01.0278831 seconds after receiving 23747904 bytes in 00:00:10.2959999 seconds
Delaying 00:00:01.0308185 seconds after receiving 25910592 bytes in 00:00:11.3243145 seconds
Shutting down socket.
Shut down socket.
Server read task completed gracefully with 0 bytes read
Server sockets disposed
Delaying 00:00:01.0298779 seconds after receiving 28073280 bytes in 00:00:12.3565051 seconds
Delaying 00:00:01.0000375 seconds after receiving 30170432 bytes in 00:00:13.3863455 seconds
Delaying 00:00:01.0305723 seconds after receiving 32333120 bytes in 00:00:14.3870607 seconds
Read all data

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment