title: How to build a robust/scalable async await echo server?
body: <p>Im building a simple TCP client and server as a basis for my networking project. Im planning to use the async await technique for future proof and scaleable server.</p>
  
  <p>If I put wrong ip address, the client cant connect to my server and throw an exception. I can catch the exception using try/catch but is that the recommended way to do?</p>
  
  <p>What do you guys think of the implementation. Any comments for me to improve?</p>
  
  <p>My server </p>
  
  <pre><code>    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");
      }
  </code></pre>
  
  <p>My client</p>
  
  <pre><code>    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 &lt; 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");
          }
  
      }
  </code></pre>