polaris% num http_cli.c 1 /* http_cli.c 2 This is a client program for getting http service. 3 Algorithm outline: 4 a. Open a TCP socket. 5 b. Initialize server socket address structure 6 c. Connect to server 7 d. Send user input to server 8 e. Loop around to display server responses on screen 9 f. Close socket. 10 This program also illustrates: 11 a. Use of gethostbyname() to get some infor. on intended server. 12 b. Use of bcopy() to copy an element into a structure. 13 Note: This client program accepts only one client request, no pipelining. 14 To compile: gcc -o http_cli http_cli.c -lsocket -lnsl 15 Command syntax: http_cli server_name (either DNS or IP) 16 Sam Hsu 17 */ 18 #include 19 #include 20 #include 21 #include 22 #include 23 #include 24 #define SER_PORT 80 /* Official HTTP port */ 25 main(int argc, char *argv[]) 26 { 27 int cli_sock, ser_len, offset; 28 ssize_t nread; 29 char buf[BUFSIZ], stdinbuf[BUFSIZ/2]; 30 struct sockaddr_in ser; 31 struct hostent *ser_info; 32 /* to open a socket */ 33 if ((cli_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 34 fprintf(stderr, "Unable to create socket for client\n"); 35 exit(1); 36 } 37 /* to initialize server sockaddr_in structure */ 38 ser_len = sizeof(ser); /* to get ser length */ 39 bzero((char *)&ser, ser_len); /* to zero out struct */ 40 ser.sin_family = AF_INET; /* Internet domain */ 41 ser.sin_port = htons(SER_PORT); /* echo server port number */ 42 /* to get some infor about the remote server */ 43 if ((ser_info = gethostbyname(argv[1])) == (struct hostent *)NULL) { 44 fprintf(stderr, "unknown server\n"); 45 exit(1); 46 } 47 bcopy((char *)ser_info->h_addr, (char *)&ser.sin_addr, ser_info->h_length); 48 /* to connect to server */ 49 if ((connect(cli_sock, (struct sockaddr *)&ser, ser_len)) == -1) { 50 fprintf(stderr, "can't connect to server\n"); 51 exit(1); 52 } 53 offset = 0; /* get user input & assemble a request */ 54 while (fgets(stdinbuf, BUFSIZ/2, stdin)) { /* no error checking */ 55 nread = strlen(stdinbuf); /* see how many char's read */ 56 strncpy(&buf[offset], stdinbuf, nread); /* copy to send buffer */ 57 offset += (int)nread; /* update offset */ 58 if (strlen(stdinbuf) == 1) { /* just a '\n' by itself */ 59 nread = (ssize_t)offset; /* total num of char's read */ 60 break; 61 } 62 } 63 send(cli_sock, buf, (size_t)nread, 0); /* send request to server */ 64 again: /* a branch label for looping */ 65 nread = recv(cli_sock, buf, BUFSIZ, 0); /* get response from server */ 66 if (nread > 0) { /* if some data received */ 67 write(STDOUT_FILENO, buf, (size_t)nread); /* display it on screen */ 68 goto again; /* not supposed to, but ...*/ 69 } 70 close(cli_sock); 71 } /* main */ polaris% http_cli www.cse.fau.edu HEAD / http/1.1 Connection: close Host: www.cse.fau.edu HTTP/1.1 200 OK Date: Tue, 01 Nov 2005 23:14:32 GMT Server: Apache/2.0.48 (Unix) mod_ssl/2.0.48 OpenSSL/0.9.7c DAV/2 PHP/4.3.4 Last-Modified: Thu, 08 Sep 2005 06:27:29 GMT ETag: "450923-11df-c15d5640" Accept-Ranges: bytes Content-Length: 4575 Connection: close Content-Type: text/html; charset=ISO-8859-1