//===================================================== file = httpget2.c =====
//=  A client program to connect to a Web server and do HTTP GETs             =
//=   - Does NUM_GET serieal GETs and does not output the response            =
//=============================================================================
//=  Notes:                                                                   =
//=    1) This program conditionally compiles for Winsock and BSD sockets.    =
//=       Set the initial #define to WIN or BSD as appropriate.               =
//=    2) This program hardwires the IP address of www.grad.csee.usf in the   =
//=       #define IP_ADDR and hardwires the GET request string into           =
//=       #define GET_STRING.                                                 =
//=---------------------------------------------------------------------------=
//=  Output from an execution (hardwired to get Christensen homepage):        =
//=                                                                           =
//=    Start of httpget2.c                                                    =
//=    End of httpget2.c                                                      =
//=---------------------------------------------------------------------------=
//=  Build: bcc32 httpget2.c, cl httpget2.c wsock32.lib,                      =
//=         gcc httpget2.c -lsocket -lnsl                                     =
//=---------------------------------------------------------------------------=
//=  Execute: httpget2                                                        =
//=---------------------------------------------------------------------------=
//=  History:  KJC (01/04/01) - Genesis (from httpget1.c)                     =
//=            KJC (10/02/12) - Updated IP address for www.csee.usf.edu       =
//=============================================================================
#define  WIN                // WIN for Winsock and BSD for BSD sockets

//----- Include files ---------------------------------------------------------
#include <stdio.h>          // Needed for printf()
#include <stdlib.h>         // Needed for exit()
#include <string.h>         // Needed for strcpy() and strlen()
#ifdef WIN
  #include <windows.h>      // Needed for all Winsock stuff
#endif
#ifdef BSD
  #include <sys/types.h>    // Needed for system defined identifiers.
  #include <netinet/in.h>   // Needed for internet address structure.
  #include <sys/socket.h>   // Needed for socket(), bind(), etc...
  #include <arpa/inet.h>    // Needed for inet_ntoa()
  #include <fcntl.h>
  #include <netdb.h>
#endif

//----- Defines ---------------------------------------------------------------
#define  BUF_SIZE            4096     // Buffer size
#define  PORT_NUM              80     // Web servers are at port 80
#define  NUM_GET               10     // Number of serial GETs to do
#define  IP_ADDR    "131.247.3.9" // IP address of www.csee.usf.edu
#define  GET_STRING "GET /~christen/index.html HTTP/1.0\n\n"  // GET string

//===== Main program ==========================================================
void main(void)
{
#ifdef WIN
  WORD wVersionRequested = MAKEWORD(1,1);    // Stuff for WSA functions
  WSADATA wsaData;                           // Stuff for WSA functions
#endif

  unsigned int         server_s;             // Server socket descriptor
  struct sockaddr_in   server_addr;          // Server Internet address
  char                 out_buf[BUF_SIZE];    // Output buffer for GET request
  char                 in_buf[BUF_SIZE];     // Input buffer for response
  unsigned int         retcode;              // Return code
  unsigned int         i;                    // Loop counter

#ifdef WIN
  // This stuff initializes winsock
  WSAStartup(wVersionRequested, &wsaData);
#endif

  // Output start message and do NUM_GET GETs
  printf("Start of httpget2.c \n");
  for (i=0; i<NUM_GET; i++)
  {
    // Create a socket
    server_s = socket(AF_INET, SOCK_STREAM, 0);

    // Fill-in the Web server socket's address information
    server_addr.sin_family = AF_INET;                 // Address family to use
    server_addr.sin_port = htons(PORT_NUM);           // Port num to use
    server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP address to use

    // Do a connect (connect() blocks)
    retcode = connect(server_s, (struct sockaddr *)&server_addr,
                      sizeof(server_addr));
    if (retcode != 0)
    {
      printf("ERROR - connect() failed \n");
      exit(1);
    }

    // Send a GET to the Web server
    strcpy(out_buf, GET_STRING);
    send(server_s, out_buf, strlen(out_buf), 0);

    // Receive from the Web server
    //  - The return code from recv() is the number of bytes received
    retcode = recv(server_s, in_buf, BUF_SIZE, 0);
    while ((retcode > 0) || (retcode == -1))
    {
      if (retcode == -1)
      {
        printf("ERROR - recv() failed \n");
        exit(1);
      }
      retcode = recv(server_s, in_buf, BUF_SIZE, 0);
    }

  // Close all open sockets
#ifdef WIN
    closesocket(server_s);
#endif
#ifdef BSD
    close(server_s);
#endif
  }

  // Output end
  printf("End of httpget2.c \n");

#ifdef WIN
  // This stuff cleans-up winsock
  WSACleanup();
#endif
}
