#include #include #include #include #include #include #include #include #include "utils.h" #define CLIENT_DEBUG 0 #define DEBUG_27 0 #define SHOW_TIMES 0 #define SIMPLE_OUTPUT 1 #define MAX_RECEIVABLE 80000 #define MAX_URL_LENGTH 80 int NUMBER_OF_REQUESTS = 1; int main(int argc, char * argv[]) { int server_socket; // conceptually a socket descriptor int returncode, addrlen; // utility variables int dest_ip_int, dest_port; int i, messagelength, bytes_sent; int requests_sent = 0; struct timeval time_holder; time_t begintime = 0 , endtime = 0; long begintimeu = 0 , endtimeu = 0; time_t overheadtime = 0, datatime = 0; long overheadtimeu = 0, datatimeu = 0; time_t alltime = 0; long alltimeu = 0; int socketn = 0, datan = 0; struct sockaddr_in server_addr; char buffer[MAX_RECEIVABLE + 1]; char url_input[MAX_URL_LENGTH+1]; char *message; url connect_to; if (!SIMPLE_OUTPUT) printf("Hi, welcome to Steve Matuszek's HTTP client for COMP 243.\n"); gettimeofday(&time_holder, NULL); alltime = time_holder.tv_sec; alltimeu = time_holder.tv_usec; if (SHOW_TIMES) printf("Starting off at %d.%06d\n", alltime, alltimeu); // Negative second, do some allocation // buffer = (char *) ((MAX_RECEIVABLE + 1) * sizeof (char)); if (!buffer) { printf("Ran out of memory trying to allocate buffer.\n"); exit(-1); } if (CLIENT_DEBUG) printf("Allocated space for buffer at memloc %d\n", buffer); // Negative first, parse args and complain about usage if (argc < 2) { printf("Usage: Client number_of_requests [url]\n"); exit(1); } else { NUMBER_OF_REQUESTS = atoi(argv[1]); } if (argc < 3) { printf("\n----------------------------------------\n"); printf("Please enter a URL. Leave blank to quit.\n> "); url_input[0] = getchar(); if (url_input[0] == '\n') { printf("Thanks for playing.\n"); exit(0); } i = 1; while (i < MAX_URL_LENGTH) { url_input[i] = getchar(); // printf("url_input[%2d] is %c\n", i, url_input[i]); if (url_input[i] == '\n') { url_input[i] = '\0'; break; } i++; } // scanf("%s", &url_input); fflush(stdin); printf("\nLooking for %s\n", url_input); } else { strcpy(url_input, argv[2]); } // Zeroth, fill the url from url_input connect_to = (url) malloc (sizeof(url_struct)); initialize_url(connect_to); returncode = parse_as_url(url_input, connect_to); if (returncode != 0) { printf("I'm sorry, I couldn't parse that URL.\n\n"); exit(1); } if (CLIENT_DEBUG) pretty_print(connect_to); dest_ip_int = get_ip_int(connect_to); if (dest_ip_int == -1) { printf("Sorry... something wrong with that one.\n"); exit(0); } dest_port = connect_to -> port; // First, create a socket // Set up server_addr to be the name of the server socket -- // we'll actually do this first since it should be unchanging, // unlike socket if (CLIENT_DEBUG) printf("Client starting up.\n"); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(dest_port); server_addr.sin_addr.s_addr = dest_ip_int; bzero(&(server_addr.sin_zero), 8); addrlen = sizeof(struct sockaddr); if (CLIENT_DEBUG) { printf("Trying to connect to port %d on host %d\n", server_addr.sin_port, server_addr.sin_addr.s_addr); } NEWCONNECTION: gettimeofday(&time_holder, NULL); begintime = time_holder.tv_sec; begintimeu = time_holder.tv_usec; if (SHOW_TIMES) printf("Socket creation begun at %d.%06d\n", begintime, begintimeu); server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket < 0) { printf("Client: error %d creating socket\n", errno); perror(" "); exit(1); } if (CLIENT_DEBUG) printf("Client: server_socket's file descriptor is %d\n", server_socket); // Connect to the server -- we're going to have to change // this part to keep the connection open... no, my mistake, // we're going to have to change it to keep making connections // if necessary. returncode = connect(server_socket, (struct sockaddr *) &server_addr, addrlen); if (returncode < 0) { printf("Client: error %d connecting\n", errno); perror(" "); exit(1); } gettimeofday(&time_holder, NULL); endtime = time_holder.tv_sec; endtimeu = time_holder.tv_usec; if (SHOW_TIMES) printf("Socket connection complete at %d.%06d\n", endtime, endtimeu); socketn++; overheadtime += (endtime - begintime); overheadtimeu += (endtimeu - begintimeu); if (SHOW_TIMES) printf("-- Overhead time so far is %d.%06d\n", overheadtime, overheadtimeu); // If we get this far we can assume we've connected. if (CLIENT_DEBUG) { printf("Connected successfully to port %d on host %d\n", server_addr.sin_port, server_addr.sin_addr.s_addr); } // So let's send a message. Actually this is where we'll // keep looping. while (requests_sent < NUMBER_OF_REQUESTS) { requests_sent++; // Let the message be HTTPish, for a reasonable amount of overhead. // We'll go ahead and fill it every time, for realism. if (DEBUG_27) printf("Sending a request...\n"); gettimeofday(&time_holder, NULL); begintime = time_holder.tv_sec; begintimeu = time_holder.tv_usec; if (SHOW_TIMES) printf("Request sent at %d.%d\n", begintime, begintimeu); allocate_and_fill_http_request(&message, connect_to); messagelength = strlen(message); bytes_sent = send(server_socket, message, messagelength, 0); // Check whether the message was sent okay. if (bytes_sent < 0) { printf("Client: error %d sending message\n", errno); perror(" "); exit(1); } else if (bytes_sent == 0) { printf("Oops...\n"); } else { if (DEBUG_27) printf("Message sent okay\n"); } // Print out as much of the message as was sent. if (CLIENT_DEBUG) { printf("The following message was successfully sent to the server:\n"); for (i = 0; i 400) { printf("Weird response code %d\n", rc); printf("Quitting Client.\n"); exit(1); } // printf("Here is your content (length == %d):\n", content_length); if (DEBUG_27) printf("Here is your content:\n"); if (DEBUG_27) printf("---------------------------------------------------\n"); if (!ignore_content_remaining) content_remaining -= strlen(buffer+content_offset); } else { if (DEBUG_27) printf(" [Not bothering to display %d bytes of stuff]\n", strlen(buffer)); if (!ignore_content_remaining) content_remaining -= strlen(buffer); } if (CLIENT_DEBUG) { printf("\n\t#################\n"); printf("\tContent remaining: %d bytes\n", content_remaining); printf("\n\t#################\n"); } } while ((content_remaining > 0) || (ignore_content_remaining && returncode != 0)); gettimeofday(&time_holder, NULL); endtime = time_holder.tv_sec; endtimeu = time_holder.tv_usec; if (SHOW_TIMES) printf("All received at %d.%d\n", endtime, endtimeu); datan++; datatime += (endtime - begintime); datatimeu += (endtimeu - begintimeu); if (SHOW_TIMES) printf(" That's a total of %d.%06d\n", (endtime-begintime), (endtimeu-begintimeu)); if (SHOW_TIMES) printf("-- Data time so far is %d.%06d\n", datatime, datatimeu); if (CLIENT_DEBUG && ignore_content_remaining) printf("Received %d bytes in last packet\n", returncode); // printf("---------------------------------------------------\n"); if (DEBUG_27) printf("\n"); } close(server_socket); gettimeofday(&time_holder, NULL); alltime = time_holder.tv_sec - alltime; alltimeu = time_holder.tv_usec - alltimeu; if (alltimeu < 0.0) { alltimeu = 1000000 + alltimeu; alltime --; } if (!SIMPLE_OUTPUT) printf("\nThe whole thing took %d.%06d seconds.\n", alltime, alltimeu); double allave = (double)alltime + ((double)alltimeu/1000000.0); if (SIMPLE_OUTPUT) printf("%.6lf\n", allave); if (!SIMPLE_OUTPUT) { printf("\nWe had to open sockets %d times.\n", socketn); printf("It took a total of %d.%06d seconds.\n", overheadtime, overheadtimeu); } if (overheadtimeu < 0.0) { overheadtimeu = 1000000 + overheadtimeu; overheadtime --; if (!SIMPLE_OUTPUT) printf("(That's %d.%06d .)\n", overheadtime, overheadtimeu); } double overheadave = (double)overheadtime + ((double)overheadtimeu/1000000.0); if (SIMPLE_OUTPUT) printf("%.6lf\n", overheadave); // overheadave /= (double) socketn; // printf("For an average of %.4lf seconds.\n", overheadave); if (!SIMPLE_OUTPUT) { printf("\nWe received data chunks %d times.\n", datan); printf("It took a total of %d.%06d seconds.\n", datatime, datatimeu); } if (datatimeu < 0.0) { datatimeu = 1000000 + datatimeu; datatime --; if (!SIMPLE_OUTPUT) printf("(That's %d.%06d .)\n", datatime, datatimeu); } double dataave = (double)datatime + ((double)datatimeu/1000000.0); if (SIMPLE_OUTPUT) printf("%.6lf\n", dataave); // dataave /= (double) datan; // printf("For an average of %.4lf seconds.\n", dataave); if (!SIMPLE_OUTPUT) { printf("So we spent %.2lf%% of our time in socket overhead,\n", 100.0*overheadave/allave); printf("compared to %.2lf%% of our time transferring data.\n", 100.0*dataave/allave); } exit(0); }