title: Simple Http proxy using Sockets: Questions
body: <p>I'm trying to learn how sockets works in C#. My idea was to program a simple http proxy:
  Here's my code:</p>
  
  <pre><code>using System;
  using System.IO;
  using System.Net;
  using System.Net.Sockets;
  using System.Text;
  using System.Text.RegularExpressions;
  using System.Threading;
  
  class Program
  {
      static void Main(string[] args)
      {
          ThreadPool.SetMaxThreads(1000, 500);
          ThreadPool.SetMinThreads(500, 250);
  
          TcpListener listener = new TcpListener(IPAddress.Any, 8282);
          listener.Start();
  
          while (true)
          {
              Socket client = listener.AcceptSocket();
              ThreadPool.QueueUserWorkItem(ProcessSocket, client);
          }
      }
  
      private static readonly string patternHostPort = @"(Host:\s)(\S+)(:)(\d+)";
      private static readonly string patternHost = @"(Host:\s)(\S+)";
      private static Regex regexHostPort = new Regex(patternHostPort);
      private static Regex regexHost = new Regex(patternHost);
  
      static void ProcessSocket(object request)
      {
          string requestString = string.Empty;
          MemoryStream mStream = new MemoryStream();
          int bytesReceived;
          int bytesSended;
          byte[] buffer;
          byte[] byteOriginalRequest;
  
          Socket socketClient = (Socket)request;
          Console.WriteLine("Incoming connection: " + socketClient.RemoteEndPoint.ToString());
  
          buffer = new byte[4096];
  
          bytesReceived = socketClient.Receive(buffer, 0, buffer.Length, SocketFlags.None);
          mStream.Write(buffer, 0, bytesReceived);
          while (socketClient.Available &gt; 0)
          {
              bytesReceived = socketClient.Receive(buffer, 0, buffer.Length, SocketFlags.None);
              mStream.Write(buffer, 0, bytesReceived);
          }
  
          mStream.Close();
  
          byteOriginalRequest = mStream.ToArray();
          requestString = Encoding.ASCII.GetString(byteOriginalRequest);
          //Console.WriteLine(requestString);
  
          #region Get requested Host and Port
          string srvHost = string.Empty;
          string srvPort = string.Empty;
  
          Match matchHostPort = regexHostPort.Match(requestString);
          if (matchHostPort.Success)
          {
              srvHost = matchHostPort.Groups[2].Value;
              srvPort = matchHostPort.Groups[4].Value;
          }
          else
          {
              Match matchHost = regexHost.Match(requestString);
              if (matchHost.Success)
              {
                  srvHost = matchHost.Groups[2].Value;
                  srvPort = "80";
              }
              else
              {
                  Console.WriteLine("Invalid request?");
              }
          }
          #endregion
  
          Console.WriteLine(string.Format("Request to {0} on port {1}", srvHost, srvPort));
  
          IPAddress[] ipAddress = Dns.GetHostAddresses(srvHost);
          IPEndPoint endPoint = new IPEndPoint(ipAddress[0], int.Parse(srvPort));
  
          using (Socket socketProxy = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
          {
              socketProxy.Connect(endPoint);
  
              bytesSended = socketProxy.Send(byteOriginalRequest, byteOriginalRequest.Length, SocketFlags.None);
  
              MemoryStream m2Stream = new MemoryStream();
              bytesReceived = 1;
              while (bytesReceived &gt; 0)
              {
                  bytesReceived = socketProxy.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                  m2Stream.Write(buffer, 0, bytesReceived);
              }
  
              m2Stream.Close();
              byte[] finalResponse = m2Stream.ToArray();
              string stringFinalResponse = Encoding.ASCII.GetString(finalResponse);
  
              bytesSended = socketClient.Send(finalResponse, finalResponse.Length, SocketFlags.None);
  
              socketProxy.Close();
          }
  
          socketClient.Close();
      }
  }
  </code></pre>
  
  <p>Here's some questions:</p>
  
  <p><strong>1)</strong> Why if I replace this</p>
  
  <pre><code>bytesReceived = 1;
  while (bytesReceived &gt; 0)
  {
      bytesReceived = socketProxy.Receive(buffer, 0, buffer.Length, SocketFlags.None);
      m2Stream.Write(buffer, 0, bytesReceived);
  }
  </code></pre>
  
  <p>with this</p>
  
  <pre><code>while (socketProxy.Available &gt; 0)
  {
      bytesReceived = socketProxy.Receive(buffer, 0, buffer.Length, SocketFlags.None);
      m2Stream.Write(buffer, 0, bytesReceived);
  }
  </code></pre>
  
  <p>I only get an empty page (in the browser)?</p>
  
  <p><strong>2)</strong> Maybe is related with 1) but ... with the current code it takes a while to load any simple page (like google), debugging i've found that the problem may be in socketProxy.Receive ... but I don't know why.</p>
  
  <p><strong>3)</strong> Is there any difference between</p>
  
  <pre><code>socketProxy.Send(byteOriginalRequest, byteOriginalRequest.Length, SocketFlags.None);
  </code></pre>
  
  <p>or</p>
  
  <pre><code>socketProxy.Send(byteOriginalRequest);
  </code></pre>
  
  <p>? (More parameters is not a valid answer :)</p>
  
  <p><strong>4)</strong> Any recommended reading? book, tutorial, ... ?</p>
  
  <p><strong>5)</strong> Any other suggestion to learn sockets?</p>
  
  <p>Thanks for your time.
  Best regards.</p>