You are on page 1of 6

#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <ctype.h> #include <netdb.h> #include <stdio.

h> #include <unistd.h> #include <time.h> #include <pthread.h> #include <string.h> #include <signal.h> #include <stdlib.h> #define SUCCESS 0 #define ERROR 1 #define SERVER_PORT 1600 #define MAX_MSG 256 /* auxillary functions to read newline-terminated strings from a file/socket */ int readnf (int, char *); int readline(int, char *, int); int server; /* listening socket descriptor */

/** * cleanup() is called to kill the thread upon SIGINT. **/ void cleanup() { close(server); pthread_exit(NULL); return; } /* cleanup() */ /** * Thread handler for incoming connections... **/ void handler(void * paramsd) { struct sockaddr_in cliAddr; char line[MAX_MSG]; char reply[MAX_MSG]; int i; int client_local; /* keep a local copy of the client's socket descriptor */ int addr_len; /* used to store length (size) of sockaddr_in */ time_t currtime; char time_msg1[6] = {'/', 'T', 'I', 'M', 'E', '\n'}; char time_msg2[6] = {'/', 'T', 'I', 'M', 'E', 13}; char quit_msg1[6] = {'/', 'Q', 'U', 'I', 'T', '\n'}; char quit_msg2[6] = {'/', 'Q', 'U', 'I', 'T', 13}; char cmd[6];

client_local = *((int *)paramsd); /* store client socket descriptor */ addr_len = sizeof(cliAddr); /* store value of size of sockaddr_in */ /* get clients name and store in cliAddr */ getpeername(client_local, (struct sockaddr*)&cliAddr, &addr_len); /* reset line */ memset(line, 0, MAX_MSG); /* now read lines from the client socket */ while(readnf(client_local, line)!=ERROR) /* loop - read from socket */ { if (!strcmp(line,"")) /* string must not be null string */ break; for (i = 0; i<6; i++) /* get first 6 chars of string, capitalize */ cmd[i] = toupper(line[i]); /* Did client ask for time? */ if (strncmp(cmd, time_msg1, 6) == 0 || strncmp(cmd, time_msg2, 6) == 0) { printf("Received /TIME from %s:%d\n", inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port)); time(&currtime); /* get current time */ strcpy(reply, ctime(&currtime)); /* copy into string */ send(client_local, reply, strlen(reply), 0); /* return current time to client */ } /* Does client want to quit? */ else if (strncmp(cmd, quit_msg1, 6) == 0 || strncmp(cmd, quit_msg2, 6) == 0) { printf("Received /QUIT from %s:%d\n", inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port)); break; } else if (strlen(line) > 2) { strcpy(reply, "You:"); strcat(reply, line); send(client_local, reply,strlen(reply),0); } /* reset line */ memset(line,0,MAX_MSG); } /* while(readnf) */ close(client_local); return; } /* handler() */ /* main function */ int main (int argc, char *argv[]) { int client; /* client socket descriptor */ int addr_len; /* used to store length (size) of sockaddr_in */ pthread_t thread; /* thread variable */ struct sockaddr_in cliAddr; struct sockaddr_in servAddr; /* socket address for client */ /* socket address for server */

signal(SIGINT, cleanup); signal(SIGTERM, cleanup);

/* now handle SIGTERM and SIGINT */

/* now create the server socket make it an IPV4 socket (PF_INET) and stream socket (TCP) and 0 to select default protocol type */ server = socket(PF_INET, SOCK_STREAM, 0); if (server < 0) { perror("cannot open socket "); return ERROR; } /* now fill in values of the server sockaddr_in struct s_addr and sin_port are in Network Byte Order (Big Endian) Since Intel CPUs use Host Byte Order (Little Endian), conversion is necessary (e.g. htons(), and htonl() */ servAddr.sin_family = AF_INET; /* again ipv4 */ servAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* local address */ servAddr.sin_port = htons(SERVER_PORT); memset(servAddr.sin_zero, 0, 8); /* now bind server port associate socket (server) with IP address:port (servAddr) */ if (bind(server, (struct sockaddr *) &servAddr, sizeof(struct sockaddr)) < 0) { perror("cannot bind port "); return ERROR; } /* wait for connection from client with a pending queue of size 5 */ listen(server, 5); while(1) /* infinite loop */ { printf("%s: waiting for data on port TCP %u\n", argv[0], SERVER_PORT); addr_len = sizeof(cliAddr); /* new socket for client connection accept() will block until a connection is present accept will return a NEW socket for the incoming connection server socket will continue listening store client address in cliAddr */ client = accept(server, (struct sockaddr *) &cliAddr, &addr_len); if (client < 0) { perror("cannot accept connection "); break; } pthread_create(&thread, 0, (void*)&handler, (void*) &client); } /* while (1) */ close(server); exit(0); } /* main() */

/** * readnf() - reading from a file descriptor but a bit smarter **/ int readnf (int fd, char *line) { if (readline(fd, line, MAX_MSG) < 0) return ERROR; return SUCCESS; } /** * readline() - read an entire line from a file descriptor until a newline. * functions returns the number of characters read but not including the * null character. **/ int readline(int fd, char *str, int maxlen) { int n; /* no. of chars */ int readcount; /* no. characters read */ char c; for (n = 1; n < maxlen; n++) { /* read 1 character at a time */ readcount = read(fd, &c, 1); /* store result in readcount */ if (readcount == 1) /* 1 char read? */ { *str = c; /* copy character to buffer */ str++; /* increment buffer index */ if (c == '\n') /* is it a newline character? */ break; /* then exit for loop */ } else if (readcount == 0) /* no character read? */ { if (n == 1) /* no character read? */ return (0); /* then return 0 */ else break; /* else simply exit loop */ } else return (-1); /* error in read() */ } *str=0; /* null-terminate the buffer */ return (n); /* return number of characters read */ } /* readline() */

client.c (download)
#include #include #include #include #include #include #include #include <sys/types.h> <sys/socket.h> <netinet/in.h> <arpa/inet.h> <netdb.h> <stdio.h> <unistd.h> /* close */ <string.h>

#include <stdlib.h> #define SERVER_PORT 1600 #define MAX_MSG 256 /* main() */ int main (int argc, char *argv[]) { int client; /* client socket */ int rc; struct sockaddr_in local_addr, serv_addr; struct hostent * host; char message[6] = {'/','T','I','M','E','\n'}; char date[25]; if(argc < 2) { printf("usage: %s <server>\n",argv[0]); exit(-1); } /* get host address from specified server name */ host = gethostbyname(argv[1]); if (host == NULL) { printf("%s: unknown host '%s'\n",argv[0],argv[1]); exit(-1); } /* now fill in sockaddr_in for remote address */ serv_addr.sin_family = host->h_addrtype; /* get first address in host, copy to serv_addr */ memcpy((char *) &serv_addr.sin_addr.s_addr, host->h_addr_list[0], host>h_length); serv_addr.sin_port = htons(SERVER_PORT); memset(serv_addr.sin_zero, 0, 8); /* create local stream socket */ client = socket(PF_INET, SOCK_STREAM, 0); if (client < 0) { perror("cannot open socket "); exit(-1); } /* bind local socket to any port number */ local_addr.sin_family = AF_INET; local_addr.sin_addr.s_addr = htonl(INADDR_ANY); local_addr.sin_port = htons(0); memset(local_addr.sin_zero, 0, 8); rc = bind(client, (struct sockaddr *) &local_addr, sizeof(local_addr)); if (rc < 0) { printf("%s: cannot bind port TCP %u\n",argv[0],SERVER_PORT); perror("error "); exit(1);

} /* connect to server */ rc = connect(client, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); if (rc < 0) { perror("cannot connect "); exit(1); } /* now send /TIME */ rc = send(client, message, strlen(message) + 1, 0); if (rc < 0) { perror("cannot send data "); close(client); exit(-1); } /* we're expecting 25 chars from server, */ read(client,date,25); printf(date); close(client); return 0; } /* main() */

You might also like