title: Socket Programming c# / Client-Server communication
body: <p>I am trying to make 2 programs (in console application) in .NET that communicate together through the web (the code is from a video that you can find below, I am just trying to make the code work before adapting it). Forgive me, I'm not an experienced programmer.</p>
  
  <p>I have a server and a client, they work perfectly when I run both of them on my computer (locally).
  I can connect multiple clients to the server, send requests and get a response.
  I am facing the problem when i run the server on a computer and the client on an other one and I try to connect through the internet.</p>
  
  <p>I can connect to the server but communication does not work, there is no data exchange when try to request time as an example. I think that the problem is mostly coming from the network itself than the code.</p>
  
  <p>Here's  the code for the server:</p>
  
  <pre><code>class Program
  {
      private static Socket _serverSocket;
      private static readonly List&lt;Socket&gt; _clientSockets = new List&lt;Socket&gt;();
      private const int _BUFFER_SIZE = 2048;
      private const int _PORT = 50114;
      private static readonly byte[] _buffer = new byte[_BUFFER_SIZE];
  
      static void Main()
      {
          Console.Title = "Server";
          SetupServer();
          Console.ReadLine(); // When we press enter close everything
          CloseAllSockets();
      }
  
  
  
      private static void SetupServer()
      {
        //  IPAddress addip = GetBroadcastAddress();
          Console.WriteLine("Setting up server...");
          _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
          _serverSocket.Bind(new IPEndPoint(IPAddress.Any , _PORT));
          _serverSocket.Listen(5);
          _serverSocket.BeginAccept(AcceptCallback, null);
          Console.WriteLine("Server setup complete");
      }
  
      /// &lt;summary&gt;
      /// Close all connected client (we do not need to shutdown the server socket as its connections
      /// are already closed with the clients)
      /// &lt;/summary&gt;
      private static void CloseAllSockets()
      {
          foreach (Socket socket in _clientSockets)
          {
              socket.Shutdown(SocketShutdown.Both);
              socket.Close();
          }
  
          _serverSocket.Close();
      }
  
      private static void AcceptCallback(IAsyncResult AR)
      {
          Socket socket;
  
          try
          {
              socket = _serverSocket.EndAccept(AR);
          }
          catch (ObjectDisposedException) // I cannot seem to avoid this (on exit when properly closing sockets)
          {
              return;
          }
  
         _clientSockets.Add(socket);
         socket.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
         Console.WriteLine("Client connected, waiting for request...");
         _serverSocket.BeginAccept(AcceptCallback, null);
      }
  
      private static void ReceiveCallback(IAsyncResult AR)
      {
          Socket current = (Socket)AR.AsyncState;
          int received;
  
          try
          {
              received = current.EndReceive(AR);
          }
          catch (SocketException)
          {
              Console.WriteLine("Client forcefully disconnected");
              current.Close(); // Dont shutdown because the socket may be disposed and its disconnected anyway
              _clientSockets.Remove(current);
              return;
          }
  
          byte[] recBuf = new byte[received];
          Array.Copy(_buffer, recBuf, received);
          string text = Encoding.ASCII.GetString(recBuf);
          Console.WriteLine("Received Text: " + text);
  
          if (text.ToLower() == "get time") // Client requested time
          {
              Console.WriteLine("Text is a get time request");
              byte[] data = Encoding.ASCII.GetBytes(DateTime.Now.ToLongTimeString());
              current.Send(data);
              Console.WriteLine("Time sent to client");
          }
          else if (text.ToLower() == "exit") // Client wants to exit gracefully
          {
              // Always Shutdown before closing
              current.Shutdown(SocketShutdown.Both);
              current.Close();
              _clientSockets.Remove(current);
              Console.WriteLine("Client disconnected");
              return;
          }
          else
          {
              Console.WriteLine("Text is an invalid request");
              byte[] data = Encoding.ASCII.GetBytes("Invalid request");
              current.Send(data);
              Console.WriteLine("Warning Sent");
          }
  
          current.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
      }
  }
  </code></pre>
  
  <p>And here the client code:</p>
  
  <pre><code>class Program
  {
      private static readonly Socket _clientSocket = new Socket
          (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  
      private const int _PORT = 50114;
  
      static void Main()
      {
          Console.Title = "Client";
          ConnectToServer();
          RequestLoop();
          Exit();
      }
  
      private static void ConnectToServer()
      {
          int attempts = 0;
  
          while (!_clientSocket.Connected)
          {
              try
              {
                  attempts++;
                  Console.WriteLine("Connection attempt " + attempts);
                  _clientSocket.Connect("IpAddr", _PORT);
              }
              catch (SocketException) 
              {
                  Console.Clear();
              }
          }
  
          Console.Clear();
          Console.WriteLine("Connected");
      }
  
      private static void RequestLoop()
      {
          Console.WriteLine(@"&lt;Type ""exit"" to properly disconnect client&gt;");
  
          while (true)
          {
              SendRequest();
              ReceiveResponse();
          }
      }
  
      /// &lt;summary&gt;
      /// Close socket and exit app
      /// &lt;/summary&gt;
      private static void Exit()
      {
          SendString("exit"); // Tell the server we re exiting
          _clientSocket.Shutdown(SocketShutdown.Both);
          _clientSocket.Close();
          Environment.Exit(0);
      }
  
      private static void SendRequest()
      {
          Console.Write("Send a request: ");
          string request = Console.ReadLine();
          SendString(request);
  
          if (request.ToLower() == "exit")
          {
              Exit();
          }
      }
  
      /// &lt;summary&gt;
      /// Sends a string to the server with ASCII encoding
      /// &lt;/summary&gt;
      private static void SendString(string text)
      {
          byte[] buffer = Encoding.ASCII.GetBytes(text);
          _clientSocket.Send(buffer, 0, buffer.Length, SocketFlags.None);
      }
  
      private static void ReceiveResponse()
      {
          var buffer = new byte[2048];
          int received = _clientSocket.Receive(buffer, SocketFlags.None);
          if (received == 0) return;
          var data = new byte[received];
          Array.Copy(buffer, data, received);
          string text = Encoding.ASCII.GetString(data);
          Console.WriteLine(text);
      }
  }
   static void Main()
      {
          Console.Title = "Client";
          ConnectToServer();
          RequestLoop();
          Exit();
      }
  
      private static void ConnectToServer()
      {
          int attempts = 0;
  
          while (!_clientSocket.Connected)
          {
              try
              {
                  attempts++;
                  Console.WriteLine("Connection attempt " + attempts);
                  _clientSocket.Connect("IpAddr", _PORT);
              }
              catch (SocketException) 
              {
                  Console.Clear();
              }
          }
  
          Console.Clear();
          Console.WriteLine("Connected");
      }
  </code></pre>
  
  <p>"IpAddr" is a placeholder for the public IP of the router.</p>
  
  <p>This is the video my current code is based on: <a href="https://www.youtube.com/watch?v=xgLRe7QV6QI" rel="nofollow">https://www.youtube.com/watch?v=xgLRe7QV6QI</a></p>
  
  <p>I took the code directly from it (you can find the 2 code files on the site linked in description).</p>
  
  <p>I run the server, it awaits for a connection. I then run the clients which tries to connect to the server. I connects and on the server it shows the successful connection. The client then sends a request like "get time" and the server is supposed to catch it and respond:</p>
  
  <pre><code> byte[] data = Encoding.ASCII.GetBytes(DateTime.Now.ToLongTimeString());
   current.Send(data);
  </code></pre>
  
  <p>Back to network side:</p>
  
  <p>Here is a list of all the things I have tried, that were the usual main causes of the problem after looking for a solution for about a full day:</p>
  
  <ul>
  <li><p>I already have a static public IP for the router (so the public IP never changes). Even though, I created a dynamic dns on noip.com.</p></li>
  <li><p>I gave a static lease to the computer the server runs on, so it has always the same local ip.</p></li>
  <li><p>I created rules in the windows firewall to make sure the port I use is opened. I did this on both computers trying to communicate.</p></li>
  <li><p>I forwarded the port on the router so it points to the local ip of the computer the server runs on. (I tried with a lot of different ports, no chance)</p></li>
  <li><p>I tried activating the "DMZ" on the router but it's most likely not a solution</p></li>
  <li><p>I tried to create a ASP.NET website which page returns a string, publish it with IIS 7.5 and set it up. Works on localhost but using the public ip like "xx.xxx.xxx.xx:PORT/default/index" I get an error. Yet it shows the website name in the error. Also, when using the local IP of the computer, it doesn't work either (something like 192.168.1.180).</p></li>
  </ul>
  
  <p>Thanks for you help.</p>