Go backward to A Simple Client-Server Example and Exercises
Go up to Top
Go forward to APPENDIX B: A Simple Server
APPENDIX A: A Simple Client
/*
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();
}
Chee Yap