Below is a modern asynchronous server using modern .NET APIs:
- Task based APIs for asynchronous accept/read/write
- Range syntax for slicing the buffer
using var listenSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(new IPEndPoint(IPAddress.Loopback, 8080));
Console.WriteLine($"Listening on {listenSocket.LocalEndPoint}");
listenSocket.Listen();
while (true)
{
// Wait for a new connection to arrive
var connection = await listenSocket.AcceptAsync();
// We got a new connection spawn a task to so that we can echo the contents of the connection
_ = Task.Run(async () =>
{
var buffer = new byte[4096];
try
{
while (true)
{
int read = await connection.ReceiveAsync(buffer, SocketFlags.None);
if (read == 0)
{
break;
}
await connection.SendAsync(buffer[..read], SocketFlags.None);
}
}
finally
{
connection.Dispose();
}
});
}
Below is a modern asynchronous client using modern .NET APIs:
- Uses Task based APIs to establish the connection.
- Creates a
NetworkStream
over theSocket
in order to useCopyToAsync
, a helper that makes it easy to copy content from oneStream
to another.
using var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
await socket.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 8080));
Console.WriteLine("Type into the console to echo the contents");
var ns = new NetworkStream(socket);
var readTask = Console.OpenStandardInput().CopyToAsync(ns);
var writeTask = ns.CopyToAsync(Console.OpenStandardOutput());
// Quit if any of the tasks complete
await Task.WhenAny(readTask, writeTask);