title: C# Connecting two tcp sockets together
body: <p>I'm not sure if the title is all that informative.</p>
  
  <p>I am trying to find/write a socket server that will accept a connection from the client (telnet) and then on behalf of the connected client, connect to one of four telnet servers inside the network.</p>
  
  <p>Once connected I keep a counter of how many connections there are, and then if there are 4 total connections, disallow any new connections until one of the four is available.</p>
  
  <p>I have written this:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Net.Sockets;
  using System.Threading;
  using System.Net;
  using System.IO;
  
  namespace ConsoleApplication1
  {
  class Program
  {
      static int nodeCount = 4;
      static int currentNode = 1;
  
      static void Main(string[] args)
      {
          ServerProgram server = new ServerProgram();
      }
  
      class ServerProgram
      {
          private TcpListener tcpPrimaryListener;
          private Thread listenThread;
  
          public ServerProgram()
          {
              this.tcpPrimaryListener = new TcpListener(IPAddress.Any, 23);
              Console.WriteLine("Telnet BBS Port Concentrator Server Started.");
              Console.WriteLine("--------------------------------------------");
  
              this.listenThread = new Thread(new ThreadStart(ListenForClients));
              this.listenThread.Start();
          }
  
          private void ListenForClients()
          {
              this.tcpPrimaryListener.Start();
  
              while (true)
              {
                  TcpClient client = this.tcpPrimaryListener.AcceptTcpClient();
                  Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                  clientThread.Start(client);
              }
          }
  
          private void HandleClientComm(object client)
          {
              if (currentNode &lt;= nodeCount)
              {
                  Console.WriteLine("Connection thread created.");
  
                  StreamWriter swStream;
                  StreamWriter swStream2;
                  StreamReader srStream;
                  StreamReader srStream2;
  
                  TcpClient tcpClient = (TcpClient)client;
                  NetworkStream tcpClientStream = tcpClient.GetStream();
  
                  TcpClient telnet = new TcpClient("192.168.100.5" + currentNode, 23);
                  NetworkStream telnetStream = telnet.GetStream();
  
                  currentNode++;
  
                  while (true)
                  {
                      srStream = new StreamReader(tcpClient.GetStream());
                      swStream2 = new StreamWriter(tcpClient.GetStream());
  
                      srStream2 = new StreamReader(telnet.GetStream());
                      swStream = new StreamWriter(telnet.GetStream());
  
                      swStream.Write(srStream.ReadToEnd());
                      swStream2.Write(srStream2.ReadToEnd());
  
                  }
              }
          }
      }
  }
  }
  </code></pre>
  
  <p>I've changed this example multiple times, so I don't really know anymore what I have and have not tried. I'm willing to try anything.</p>
  
  <p>The purpose is actually running this to allow one telnet port open through the firewall, and allowing connections into a small network of DOS machines running telnet fossil driver BBS software. I would just like to redirect telnet traffic to an available system using only one port.</p>
  
  <p>The problem is that I cannot figure out how to actually connect the two sockets together and pass data between them as it happens. The incoming socket and the socket I created on behalf of the server to the server.</p>
  
  <p>Thanks.</p>
  
  <p>UPDATE:</p>
  
  <p>This is what is working for me, I'm still looking over for bugs but it's working so far.</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Net.Sockets;
  using System.Threading;
  using System.Net;
  using System.IO;
  using System.Threading.Tasks;
  
  namespace ConsoleApplication1
  {
  class Program
  {
      static int nodeCount = 2;
      static int currentNode = 1;
  
      static void Main(string[] args)
      {
          ServerProgram server = new ServerProgram();
      }
  
      class ServerProgram
      {
          private TcpListener tcpPrimaryListener;
          private Thread listenThread;
  
          public ServerProgram()
          {
              this.tcpPrimaryListener = new TcpListener(IPAddress.Any, 23);
              Console.WriteLine("Telnet BBS Port Concentrator Server Started.");
              Console.WriteLine("--------------------------------------------");
  
              this.listenThread = new Thread(new ThreadStart(ListenForClients));
              this.listenThread.Start();
          }
  
          private void ListenForClients()
          {
              this.tcpPrimaryListener.Start();
  
              while (true)
              {
                  TcpClient client = this.tcpPrimaryListener.AcceptTcpClient();
                  Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                  clientThread.Start(client);
              }
          }
  
          private void HandleClientComm(object client)
          {
              string noNodes = "Sorry all nodes are occupied.";
  
              if (currentNode &lt;= nodeCount)
              {
                  Console.WriteLine("Client connected.");
  
                  TcpClient tcpClient = (TcpClient)client;
                  NetworkStream tcpClientStream = tcpClient.GetStream();
  
                  TcpClient telnet = new TcpClient("10.24.9.11", 23);
                  //TcpClient telnet = new TcpClient("192.168.100.5" + currentNode, 23);
                  NetworkStream telnetStream = telnet.GetStream();
  
                  currentNode++;
  
                  ByPass linkedSockets = new ByPass(tcpClientStream, telnetStream);
              }
              else
              {
                  TcpClient tcpClient = (TcpClient)client;
                  NetworkStream tcpClientStream = tcpClient.GetStream();
  
                  ASCIIEncoding encoder = new ASCIIEncoding();
                  tcpClientStream.Write(Encoding.ASCII.GetBytes(noNodes), 0, noNodes.Length);
              }
          }
      }
  
      public class ByPass
      {
          public ByPass(Stream s1, Stream s2)
          {
              var cTokenSource = new CancellationTokenSource();
              var cToken = cTokenSource.Token;
              Task.Factory.StartNew(() =&gt; Process(s1, s2, cToken, cTokenSource), cToken);
              Task.Factory.StartNew(() =&gt; Process(s2, s1, cToken, cTokenSource), cToken);
              cToken.Register(() =&gt; cancelNotification());
          }
  
          public void Process(Stream s1, Stream s2, CancellationToken ct, CancellationTokenSource cTokenSource)
          {
              byte[] buf = new byte[0x10000];
  
              while (true)
              {
                  if (ct.IsCancellationRequested)
                  {
                      break;
                  }
  
                  try
                  {
                      int len = s1.Read(buf, 0, buf.Length);
                      s2.Write(buf, 0, len);
                  }
                  catch
                  {
                      s1.Close(); s2.Close();
                      cTokenSource.Cancel();
                      break;
                  }
              }
          }
      }
  
      static void cancelNotification()
      {
          Console.WriteLine("Client disconnected.");
          currentNode--;
      }
  }
  }
  </code></pre>