title: C# - Sockets: Port Forwarding
body: <p>I am working at a Network Program but when I testing the code I find out that my friends (they are not in my local network) cant connect to the server. Now I found out that port forwarding could be the probleme but I dont know how I can change my code, that my friends can connect (when port forwarding the problem is than how can I implement port forwarding in my code).
  Here my Classes:
  Server class:</p>
  
  <pre><code>    static Socket listenerSocket;
      static List&lt;ClientData&gt; clients;
      static List&lt;ClientName&gt; clientNames;
      static List&lt;ClientName&gt; clientReady;
      private int port;
  
      public Server(int port)
      {
          InitializeComponent();
          this.port = port;
      }
      private void Server_Load(object sender, EventArgs e)
      {
          Start();
      }
  
      private void Start()
      {
          consoleList.Items.Add("Starting Server on " + Packet.GetIP4Address() + ":" + port);
  
          listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
          clients = new List&lt;ClientData&gt;();
          clientNames = new List&lt;ClientName&gt;();
          clientReady = new List&lt;ClientName&gt;();
  
          IPEndPoint point = new IPEndPoint(IPAddress.Parse(Packet.GetIP4Address()), port);
          try
          {
              listenerSocket.Bind(point);
          }
          catch (Exception)
          {
              MessageBox.Show("Port ist schon benutzt!");
              Close();
          }
  
          Thread listenThread = new Thread(ListenThread);
          listenThread.Start();
      }
  
      static void ListenThread()
      {
          for (;;)
          {
              listenerSocket.Listen(0);
              ClientData data = new ClientData(listenerSocket.Accept());
              clients.Add(data);
          }
      }
  
      public static void ResetReadyClientList()
      {
          ResetReadyClientList_Server();
      }
  
      private static void ResetReadyClientList_Server()
      {
          clientReady.Clear();
      }
  
      public static List&lt;ClientName&gt; GetReadyClientList()
      {
          return clientReady;
      }
  
      public static List&lt;ClientName&gt; GetClientList()
      {
          return clientNames;
      }
  
      public static void Data_IN(object cSocket)
      {
          Socket clientScoket = (Socket)cSocket;
  
          byte[] buffer;
          int readBytes;
  
          for (;;)
          {
              buffer = new byte[clientScoket.SendBufferSize];
  
              readBytes = clientScoket.Receive(buffer);
  
              if(readBytes &gt; 0)
              {
                  Packet packet = new Packet(buffer);
                  DataManager(packet);
              }
          }
      }
  
      static List&lt;String&gt; packetsReceived = new List&lt;string&gt;();
      static List&lt;String&gt; clientsHasDownloaded = new List&lt;string&gt;();
  
      static String path;
  
      public static void DataManager(Packet p)
      {
          switch (p.packetType)
          {
              case PacketType.OutWindow:
                  String name = GetName(p.senderID);
                  MessageBox.Show(name + " hat aus dem Fenster geklickt!");
                  break;
              case PacketType.RegisterName:
                  ClientName cName = new ClientName(p.senderID, p.gData[0]);
  
                  clientNames.Add(cName);
                  break;
              case PacketType.Answer:
                  String senderName = GetName(p.senderID);
                  String answer = p.gData[0];
                  MessageBox.Show("Spieler " + senderName + " hat " + answer + " getippt!");
                  ClientName c = new ClientName(p.senderID, GetName(p.senderID));
                  if (clientReady.Contains(c)) clientReady.Remove(c);
                  clientReady.Add(c);
                  break;
              case PacketType.HasDownloaded:
                  clientsHasDownloaded.Add(p.senderID);
                  if (clientsHasDownloaded.Count == clients.Count)
                  {
                      SoundHostForm form = new SoundHostForm();
                      form.ShowDialog();
                      path = p.gData[0];
                  }
                  break;
          }
      }
  
      static ClientData GetClientData(String id)
      {
          foreach (ClientData c in clients)
          {
              if(c.id == id)
              {
                  return c;
              }
          }
          return null;
      }
  
      public static void SendFileToAll(String path)
      {
          Thread t = new Thread(() =&gt; SendFile(path));
          t.Start();
      }
  
      private static void SendFile(String path)
      {
          clientsHasDownloaded.Clear();
  
          Uri downloadLink = FileTransfer.UploadFile(path);
  
          Packet p = new Packet(PacketType.CanDownload, "server");
          p.gData.Add(downloadLink.ToString());
  
          foreach (ClientData data in clients)
          {
              data.clientSocket.Send(p.ToBytes());
          }
      }
  
      public static void SendPacketToAll(Packet p)
      {
          foreach(ClientData data in clients)
          {
              data.clientSocket.Send(p.ToBytes());
          }
      }
  
      static String GetName(String id)
      {
          foreach (ClientName c in clientNames)
          {
              if (c.id == id)
              {
                  return c.name;
              }
          }
          return null;
      }
  
  }
  class ClientData
  {
      public Socket clientSocket;
      public Thread clientThread;
      public String id;
  
      public ClientData()
      {
          id = Guid.NewGuid().ToString();
          clientThread = new Thread(Server.Data_IN);
          clientThread.Start(clientSocket);
          SendRegisterationPacket();
      }
  
      public ClientData(Socket clientSocket)
      {
          this.clientSocket = clientSocket;
          id = Guid.NewGuid().ToString();
          clientThread = new Thread(Server.Data_IN);
          clientThread.Start(clientSocket);
          SendRegisterationPacket();
      }
  
      public void SendRegisterationPacket()
      {
          Packet p = new Packet(PacketType.Registration, "server");
          p.gData.Add(id);
          clientSocket.Send(p.ToBytes());
      }
  }
  
  public class ClientName
  {
      public String id;
      public String name;
  
      public ClientName(String id, String name)
      {
          this.id = id;
          this.name = name;
      }
  }
  </code></pre>
  
  <p>Client:</p>
  
  <pre><code>public static Socket master;
      public string username;
      public static string id;
      private String ip;
      private int port;
  
      public Client(String username, String ipPortString)
      {
          InitializeComponent();
          this.username = username;
          ip = ipPortString.Split(':')[0];
          port = Convert.ToInt32(ipPortString.Split(':')[1]);
      }
      private void Client_Load(object sender, EventArgs e){}
  
      public void Start()
      {
          master = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  
          IPEndPoint point = new IPEndPoint(IPAddress.Parse(ip), port);
          try
          {
              master.Connect(point);
          }
          catch
          {
              MessageBox.Show("Fehler beim Verbinden! Code: 0x156f237" + "\n" + "Der Server konnte nicht gefunden werden!");
              Thread.Sleep(1000);
              Start();
          }
          Thread t = new Thread(Data_IN);
          t.Start();
      }
  
      void Data_IN()
      {
              byte[] buffer;
              int readBytes;
  
              for (;;)
              {
                  buffer = new byte[master.SendBufferSize];
                  readBytes = master.Receive(buffer);
  
                  if (readBytes &gt; 0)
                  {
                      DataManager(new Packet(buffer));
                  }
              }
      }
  
      static List&lt;String&gt; packetsReceived = new List&lt;string&gt;();
      static TippForm tippFormCache;
  
      void DataManager(Packet p)
      {
          PacketType type = p.packetType;
          switch (type)
          {
              case PacketType.Registration:
                  id = p.gData[0];
                  Packet rp = new Packet(PacketType.RegisterName, id);
                  rp.gData.Add(username);
                  master.Send(rp.ToBytes());
                  break;
              case PacketType.Window:
                  String windowID = p.gData[0];
                  if (windowID == ABCDForm.SERIALAZIE_ID)
                  {
                      if (p.senderID == "server")
                      {
                          if (!packetsReceived.Contains(p.packetID))
                          {
                              ABCDForm form = new ABCDForm(id, p.gData[1], p.gData[2], p.gData[3], p.gData[4], p.gData[5]);
                              if (!IsOpened(form))
                              {
                                  form.ShowDialog();
                                  packetsReceived.Add(p.packetID);
                              }
                          }
                      }
                  }
                  else if (windowID == OpenAnswerForm.SERIALIZE_ID)
                  {
                      if (p.senderID == "server")
                      {
                          if (!packetsReceived.Contains(p.packetID))
                          {
                              OpenAnswerForm form = new OpenAnswerForm(id, p.gData[1]);
                              if (!IsOpened(form))
                              {
                                  form.ShowDialog();
                                  packetsReceived.Add(p.packetID);
                              }
                          }
                      }
                  }
                  else if (windowID == TippForm.SERIALIZE_ID)
                  {
                      if (p.senderID == "server")
                      {
                          if (!packetsReceived.Contains(p.packetID))
                          {
                              tippFormCache = new TippForm(id, p.gData[1], p.gData[2], p.gData[3], p.gData[4], p.gData[5]);
                              if (!IsOpened(tippFormCache))
                              {
                                  tippFormCache.ShowDialog();
                                  packetsReceived.Add(p.packetID);
                              }
                          }
                      }
                  }
                  else if (windowID == SoundForm.SERIALAZIE_ID)
                  {
                      if (p.senderID == "server")
                      {
                          if (!packetsReceived.Contains(p.packetID))
                          {
                              SoundForm form = new SoundForm(id, p.gData[1]);
                              if (!IsOpened(form))
                              {
                                  form.ShowDialog();
                                  packetsReceived.Add(p.packetID);
                              }
                          }
                      }
                  }
                  else if (windowID == VideoPlayerForm.SERIALIZE_ID)
                  {
                      if (p.senderID == "server")
                      {
                          if (!packetsReceived.Contains(p.packetID))
                          {
                              playerForm = new VideoPlayerForm(id);
                              if (!IsOpened(playerForm))
                              {
                                  Thread t = new Thread(() =&gt; OpenVideoPlayerWithSTA(p));
                                  t.SetApartmentState(ApartmentState.STA);
                                  t.Start();
                              }
                          }
                      }
                  }
                  break;
              case PacketType.OpenNewTipp:
                  if(tippFormCache != null)
                  {
                      tippFormCache.OpenNewTipp();
                  }
                  break;
              case PacketType.CanDownload:
                  if(p.senderID == "server")
                  {
                      Uri downloadLink = new Uri(p.gData[0]);
  
                      String uri = FileTransfer.DownloadFile(downloadLink);
  
                      Packet replyPacket = new Packet(PacketType.HasDownloaded, id);
                      replyPacket.gData.Add(uri);
                      master.Send(replyPacket.ToBytes());
                  }
                  break;
              case PacketType.Play:
                  if (IsOpened(playerForm))
                  {
                      playerForm.Start();
                  }
                  break;
              case PacketType.TogglePause:
                  if (IsOpened(playerForm))
                  {
                      playerForm.Pause();
                  }
                  break;
              case PacketType.Stop:
                  if (IsOpened(playerForm))
                  {
                      playerForm.Stop();
                  }
                  break;
          }
      }
  
      private static void OpenVideoPlayerWithSTA(Packet p)
      {
          playerForm.ShowDialog();
          packetsReceived.Add(p.packetID);
      }
  
      private static VideoPlayerForm playerForm;
  
      private static bool IsOpened(Form form)
      {
          FormCollection fc = Application.OpenForms;
          foreach(Form f in fc)
          {
              if(f == form)
              {
                  return true;
              }
          }
          return false;
      }
  </code></pre>
  
  <p>And my Packet Class / Server Data:</p>
  
  <pre><code>[Serializable]
  public class Packet
  {
      public List&lt;String&gt; gData;
      public int packetInt;
      public bool packetBool;
      public string senderID;
      public PacketType packetType;
      public string packetID;
  
      public Packet(PacketType packetType, string senderID)
      {
          gData = new List&lt;String&gt;();
          this.senderID = senderID;
          this.packetType = packetType;
          packetID = Guid.NewGuid().ToString();
      }
  
      public Packet(byte[] bytes)
      {
          BinaryFormatter bf = new BinaryFormatter();
          MemoryStream ms = new MemoryStream(bytes);
  
          ms.Position = 0;
  
          Packet p = (Packet)bf.Deserialize(ms);
          ms.Close();
  
          gData = p.gData;
          packetBool = p.packetBool;
          packetInt = p.packetInt;
          packetType = p.packetType;
          senderID = p.senderID;
          packetID = Guid.NewGuid().ToString();
      }
  
      public byte[] ToBytes()
      {
          BinaryFormatter bf = new BinaryFormatter();
          MemoryStream ms = new MemoryStream();
  
          ms.Position = 0;
  
          bf.Serialize(ms, this);
          byte[] bytes = ms.ToArray();
          ms.Close();
          return bytes;
      }
  
      public static string GetIP4Address()
      {
          IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
  
          foreach(IPAddress ip in ips)
          {
              if(ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
              {
                  return ip.ToString();
              }
          }
          return "127.0.0.1";
      }
  }
  
  public enum PacketType
  {
      Registration,
      Window,
   /*[0] = FormID
   *
   * ABCD:
   * [1] = Frage
   * [2] = A
   * [3] = B
   * [4] = C
   * [5] = D
   * 
   * OPEN:
   * [1] = Frage
   * 
   * TIPP:
   * [1] = 1. Tipp
   * [2] = 2. Tipp
   * [3] = 3. Tipp
   * [4] = 4. Tipp
   * [5] = 5. Tipp
   * 
   * SOUND:
   * [1] = Uri
   */
      Answer,//[0] = Antwort
      OutWindow,
      RegisterName,
      Play,
      TogglePause,
      Stop,
      OpenNewTipp,
      CanDownload,
      HasDownloaded
  }
  </code></pre>
  
  <p>I hope you can help me guys.</p>