C#: a TCP echo server on the loopback interface

TCP provides a reliable byte stream between two endpoints. A server creates a TcpListener bound to an address and port, starts listening, and accepts connections. A client creates a TcpClient and connects to the server's address and port. Both sides read and write through a NetworkStream.

C#
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;

class Program {
  static async Task Main() {
    var listener = new TcpListener(IPAddress.Loopback, 0);
    listener.Start();
    int port = ((IPEndPoint)listener.LocalEndpoint).Port;

    Task server = Task.Run(async () => {
      using TcpClient accepted = await listener.AcceptTcpClientAsync();
      using var reader = new StreamReader(accepted.GetStream());
      using var writer = new StreamWriter(accepted.GetStream()) { AutoFlush = true };
      string line = await reader.ReadLineAsync();
      await writer.WriteLineAsync("echo: " + line);
    });

    using (var client = new TcpClient()) {
      await client.ConnectAsync(IPAddress.Loopback, port);
      using var reader = new StreamReader(client.GetStream());
      using var writer = new StreamWriter(client.GetStream()) { AutoFlush = true };
      await writer.WriteLineAsync("hello");
      Console.WriteLine(await reader.ReadLineAsync());
    }
    await server;
    listener.Stop();
  }
}
Read the full lesson