A more fully commented version of this client program
/* Author : Ting-jen Yen (yentj@cs.nyu.edu) file name : client.c related files: server.c Description : This is the client side program of a simple TCP client-server test program. It simply reads a number (unsigned, integer or float) from the user input, sends it to the server (see server.c file), and then display everything returned from the server. This is repeated until the user types "quit", at which point both sides will close the connection. Usage: Simply type "client" to access the server at jinai.cs.nyu.edu, at default port 1234. The general format is % client [<server_addr>] [-p <port number>] How to compile : On Solaris 2 : % gcc -o client client.c -lsocket -lnsl On SGI machines or Linux machines: % gcc -o client client.c */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/socket.h> #include <sys/errno.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <fcntl.h> #include <string.h> #include <signal.h> #include <sys/types.h> int con_sock; int srv_port = 1234; char host[128]; /* Received a signal. Close the connection and quit. */ void signal_handler() { close(con_sock); exit(0); } /* establish_connection() will do what its name suggests: makes a connection to the server. It will use the global variables host and srv_port as input. Then it will update the value of con_sock, which is the file descriptor of the socket used for communicating with the server. */ establish_connection() { struct sockaddr_in name; struct hostent *hptr; int flag; /* create a socket */ con_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (con_sock <= 0) { perror("Open socket failed"); exit(1); } name.sin_family = AF_INET; name.sin_port = htons(srv_port); /* getting the host IP information */ if ((hptr = gethostbyname(host)) == NULL) { perror("gethostbyname"); exit(1); } bcopy(hptr->h_addr, &name.sin_addr.s_addr, hptr->h_length); printf("Trying to contact %s...\n", host); /* making connection */ flag = connect(con_sock, (struct sockaddr *) &name, sizeof(name)); if (flag < 0) { perror("No connection"); close(con_sock); exit(1); } printf("Connected\n"); } extern int errno; /* make_trans() will get user input, put them to the server, and then display the return message from the server. */ make_trans() { char buff[1024], out[1024]; int lg, flag; flag = 1; do { /* getting one line from standard input */ gets(buff); sprintf(out, "%s\r\n", buff); /* write everything to the network. */ lg = write(con_sock, out, strlen(out)); /* If having any trouble with the socket, it means that the connection is closed somehow, quit the program. */ if (lg == -1 && errno == EBADF) goto error; /* If the user input is "quit", then end the loop. */ if (strncmp(buff, "quit", 4) == 0) { flag = 0; break; } do { /* get response from the server. If therer is error and it is EBADF, it means the connection might be closed, otherwise, try to read it again until we read it successfully. */ lg = read(con_sock, buff, 1024); if (lg == -1 && errno == EBADF) goto error; } while (lg <= 0); if (buff[lg - 1] != '\n' || buff[lg - 2] != '\r') { fprintf(stderr, "Error: Wrong format\r\n"); } /* Display the response to standard output */ buff[lg - 1] = '\0'; buff[lg - 2] = '\n'; printf("%s", buff); } while (flag); /* close the connection if */ error: close(con_sock); } usage() { fprintf(stderr, "usage: client [-p port]\n"); exit(1); } main(argc, argv) int argc; char **argv; { int lg; /* shift the parameters */ argc--; argv++; /* set initial value of the server. */ strcpy(host, "jinai.cs.nyu.edu"); while (argc > 0) { if (argv[0][0] != '-') { /* setting new server name */ strcpy(host, argv[0]); argv ++; argc --; continue; } switch (argv[0][1]) { /* setting port number */ case 'p': srv_port = atoi(argv[1]); argv += 2; argc -= 2; break; default: usage(); } } /* Intercept some signals so we can quit the program more gracefully when interrupted by such signals. */ signal(SIGTERM, signal_handler); signal(SIGQUIT, signal_handler); signal(SIGINT, signal_handler); establish_connection(); make_trans(); }