I want to build a robust and highly scalable client server system. Here what I have so far(an echo server as my base of implementation)My Server    private void startServer_Click(object sender, RoutedEventArgs e)    {        if (anyIP.IsChecked == true)        {            listener = new TcpListener(IPAddress.Any, Int32.Parse(serverPort.Text));            Logger.Info(Ip Address :  + IPAddress.Any +  Port :  + serverPort.Text);        }        else        {            listener = new TcpListener(IPAddress.Parse(serverIP.Text), Int32.Parse(serverPort.Text));            Logger.Info(Ip Address :  + serverIP.Text +  Port :  + serverPort.Text);        }        try        {            listener.Start();            Logger.Info(Listening);            HandleConnectionAsync(listener, cts.Token);        }        //finally        //{            //cts.Cancel();            //listener.Stop();            //Logger.Info(Stop listening);        //}        //cts.Cancel();    }    async Task HandleConnectionAsync(TcpListener listener, CancellationToken ct)    {        while (!ct.IsCancellationRequested)        {            Logger.Info(Accepting client);            //TcpClient client = await listener.AcceptTcpClientAsync();            TcpClient client = await listener.AcceptTcpClientAsync();            Logger.Info(Client accepted);            EchoAsync(client, ct);        }    }    async Task EchoAsync(TcpClient client, CancellationToken ct)    {        var buf = new byte[4096];        var stream = client.GetStream();        while (!ct.IsCancellationRequested)        {            var amountRead = await stream.ReadAsync(buf, 0, buf.Length, ct);            Logger.Info(Receive  + stream.ToString());            if (amountRead == 0) break; //end of stream.            await stream.WriteAsync(buf, 0, amountRead, ct);            Logger.Info(Echo to client);        }    }    private void stopServer_Click(object sender, RoutedEventArgs e)    {        cts.Cancel();        listener.Stop();        Logger.Info(Stop listening);    }My Client    private void connect_Click(object sender, System.Windows.RoutedEventArgs e)    {        IPAddress ipAddress;        int port;        //TODO Check if ip address is valid        ipAddress = IPAddress.Parse(serverIP.Text);        //TODO port range is 0-65000        port = int.Parse(serverPort.Text);        StartClient(ipAddress, port);    }    private static async void StartClient(IPAddress serverIpAddress, int port)    {        var client = new TcpClient();        //can i try/catch to catch await exception?        try        {            await client.ConnectAsync(serverIpAddress, port);        }        catch (Exception e)        {            Logger.Info(e);                        }        Logger.Info(Connected to server);        using (var networkStream = client.GetStream())        using (var writer = new StreamWriter(networkStream))        using (var reader = new StreamReader(networkStream))        {            writer.AutoFlush = true;            for (int i = 0; i < 10; i++)            {                Logger.Info(Writing to server);                await writer.WriteLineAsync(DateTime.Now.ToLongDateString());                Logger.Info(Reading from server);                var dataFromServer = await reader.ReadLineAsync();                if (!string.IsNullOrEmpty(dataFromServer))                {                    Logger.Info(dataFromServer);                }            }        }        if (client != null)        {            client.Close();            Logger.Info(Connection closed);        }    }
WPF async await TcpClient/TcpListener sample
c#;tcp;async await