title: C++ TCP Proxy and Socket Programming
body: <p>Okay, I've scoured the net (literally) for the last ten hours, but no one seems to have a tutorial explaining how to create a C++ Proxy server in Windows. Several times I've run into functions that work solely for UNIX, and it's been a frustrating experience. I am VERY new to socket programming, but I need to have this finished within 48 hours. It seems impossible right now.</p>
  
  <p>Requirements for the program:</p>
  
  <ul>
  <li>The daemon listens for TCP connections on a specified port number.</li>
  <li>When a new client initiates a TCP connection request, the daemon accepts
  the request and establishes a TCP connection with the new client.</li>
  <li>The daemon forks a child process that is dedicated to handling the new
  client.</li>
  <li>The child process establishes a TCP connection to a pre-assigned port on the
  actual targeted server.</li>
  <li>The child process falls into a loop in which it acts as an intermediator
  exchanging data (reading/writing or writing/reading) between the client and
  the targeted server.</li>
  <li>Once a child has been forked, the daemon process resumes listening for
  additional TCP connections.</li>
  </ul>
  
  <p>I've run a provided winsock client and program to get a better idea of how sockets work, but it's getting me nowhere fast. <code>pid_t</code> is unavailable for windows, so forking is out of the question (or so I've gathered from the 10 hours of net-scouring). </p>
  
  <p>If you can point me in the right direction for being able to use Internet Explorer's proxy settings (the IP and Port number feature) in combination with the program to yield webpages that are redirected to another server, that would be great. </p>
  
  <pre><code>/* client.c - code for example client program that uses TCP */
  
  
  #ifndef unix
  #include&lt;winsock2.h&gt;
  #include &lt;windows.h&gt;
  #include &lt;winsock.h&gt; 
  #pragma comment(lib, "ws2_32.lib")
  
  
  #else
  #define closesocket close
  #include &lt;sys/types.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;sys/param.h&gt;
  #endif
  
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;iostream&gt;
  
  #define PROTOPORT       5193            /* default protocol port number */
  
  extern "C";
  char    localhost[] =   "localhost";    /* default host name            */
  #define QLEN 6                          /* size of request queue        */
  
  int     visits      =   0;              /* counts client connections    */
  /*------------------------------------------------------------------------
   * Program:   client
   *
   * Purpose:   allocate a socket, connect to a server, and print all output
   *
   * Syntax:    client [ host [port] ]
   *
   *               host  - name of a computer on which server is executing
   *               port  - protocol port number server is using
   *
   * Note:      Both arguments are optional.  If no host name is specified,
   *            the client uses "localhost"; if no protocol port is
   *            specified, the client uses the default given by PROTOPORT.
   *
   *------------------------------------------------------------------------
   */
  int main(int argc, char *argv[])
  {               
          struct  hostent  *ptrh;  /* pointer to a host table entry       */
          struct  protoent *ptrp;  /* pointer to a protocol table entry   */
          struct  sockaddr_in sad; /* structure to hold an IP address     */
          int     port;            /* protocol port number                */
          char    *host;           /* pointer to host name                */
          int     n;               /* number of characters read           */
          char    buf[1000];       /* buffer for data from the server     */
          struct  sockaddr_in cad; /* structure to hold client's address  */
          int     sd, sd2;         /* socket descriptors                  */
          int     alen;            /* length of address                   */
  
  #ifdef WIN32
          WSADATA wsaData;
          WSAStartup(0x0101, &amp;wsaData);
  #endif
          memset((char *)&amp;sad,0,sizeof(sad)); /* clear sockaddr structure */
          sad.sin_family = AF_INET;         /* set family to Internet     */
          sad.sin_addr.s_addr = INADDR_ANY; /* set the local IP address   */
  
          /* Check command-line argument for protocol port and extract    */
          /* port number if one is specified.  Otherwise, use the default */
          /* port value given by constant PROTOPORT                       */
  
          if (argc &gt; 2) {                 /* if protocol port specified   */
                  port = atoi(argv[2]);   /* convert to binary            */
          } else {
                  port = PROTOPORT;       /* use default port number      */
          }
              if (port &gt; 0)                   /* test for legal value         */
                  sad.sin_port = htons((u_short)port);
          else {                          /* print error message and exit */
                  fprintf(stderr,"bad port number %s\n",argv[2]);
                  exit(1);
  
           if (argc &gt; 1) {                 /* if argument specified        */
                  port = atoi(argv[1]);   /* convert argument to binary   */
          } else {
              port = PROTOPORT;       /* use default port number      */
      }
      if (port &gt; 0)                   /* test for illegal value       */
              sad.sin_port = htons((u_short)port);
      else {                          /* print error message and exit */
              fprintf(stderr,"bad port number %s\n",argv[1]);
              exit(1);
      }
  
      /* Map TCP transport protocol name to protocol number */
      (int)(ptrp = getprotobyname("tcp"));
      if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) {
              fprintf(stderr, "cannot map \"tcp\" to protocol number");
              exit(1);
      }
  
      /* Check host argument and assign host name. */
  
      if (argc &gt; 1) {
              host = argv[1];         /* if host argument specified   */
      } else {
              host = localhost;
      }
  
      /* Convert host name to equivalent IP address and copy to sad. */
  
      ptrh = gethostbyname(host);
      if ( ((char *)ptrh) == NULL ) {
              fprintf(stderr,"invalid host: %s\n", host);
              exit(1);
      }
      memcpy(&amp;sad.sin_addr, ptrh-&gt;h_addr, ptrh-&gt;h_length);
  
      /* Map TCP transport protocol name to protocol number. */
      (int)(ptrp = getprotobyname("tcp"));
      if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) {
              fprintf(stderr, "cannot map \"tcp\" to protocol number");
              exit(1);
      }
  
      /* Create a socket. */
  
      sd = socket(PF_INET, SOCK_STREAM, ptrp-&gt;p_proto);
      if (sd &lt; 0) {
              fprintf(stderr, "socket creation failed\n");
              exit(1);
      }
  
      /* Connect the socket to the specified server. */
      connect(sd, (struct sockaddr *)&amp;sad, sizeof(sad));
      if (connect(sd, (struct sockaddr *)&amp;sad, sizeof(sad)) &lt; 0) {
              fprintf(stderr,"connect failed\n");
              exit(1);
      }
  
       /* Bind a local address to the socket */
      bind(sd, (struct sockaddr *)&amp;sad, sizeof(sad));
      if (bind(sd, (struct sockaddr *)&amp;sad, sizeof(sad)) &lt; 0) {
              fprintf(stderr,"bind failed\n");
              exit(1);
      }
  
      /* Specify size of request queue */
      listen(sd, QLEN);
      if (listen(sd, QLEN) &lt; 0) {
              fprintf(stderr,"listen failed\n");
              exit(1);
      }
  
      /* Repeatedly read data from socket and write to user's screen. */
  
      n = recv(sd, buf, sizeof(buf), 0);
      while (n &gt; 0) {
              int _write(int fd, const void *buffer, unsigned int count);
              n = recv(sd, buf, sizeof(buf), 0);
      }
  
       /* Main server loop - accept and handle requests */
  
      while (1) {
              alen = sizeof(cad);
      printf("\nI'm waiting for connections ...");
      fflush(stdout);
              if ( (sd2=accept(sd, (struct sockaddr *)&amp;cad, &amp;alen)) &lt; 0) {
                      fprintf(stderr, "accept failed\n");
                      exit(1);
              }
      printf("\nI received one connection.\n");
      fflush(stdout);
              visits++;
              sprintf_s(buf,"This server has been contacted %d time%s\n",
                      visits,visits==1?".":"s.");
              send(sd2,buf,strlen(buf),0);
      printf("\nI sent the client a string.\n");
      fflush(stdout);
              closesocket(sd2);
      }
  
  
      /* Close the socket. */
  
      closesocket(sd);
  
      /* Terminate the client program gracefully. */
  
      exit(0);
  }
  }
  </code></pre>
  
  <p>If you've made it this far, I thank you for your vigilance. Wish me luck...</p>