home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_09_09
/
9n09048a
< prev
next >
Wrap
Text File
|
1991-07-17
|
6KB
|
151 lines
Listing 1. The stream sockets example. Server program.
/* receive -- the server program. It runs in the background listening for
* client connections. Remote or local clients send character strings to the
* server that receives them and echoes them on the server side. The present
* program operates in conjunction with one or more client programs called
* "send".
* Usage: receive &
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#define FAIL 1 /* exit code in case of failure */
#define SUCC 0 /* correct termination code */
#define PORT_NUMBER 2227 /* arbitrarily chosen port number for
* client-server communication. Must be
* non-reserved (> 1023) and the same in
* client and server
*/
#define MAX_CONN 5 /* maximum number of connection requests
* that can be queued.
*/
int sock_descr ; /* listen socket descriptor */
int new_sockds ; /* connected socket descriptor */
struct sockaddr_in client_addr ; /* peer socket address */
/* ------------------------------------------------------------------- */
main()
{
void error(), server() ;
struct sockaddr_in my_sock_addr ; /* local socket address structure */
int length = sizeof(struct sockaddr) ;
/* create the listen socket */
if ((sock_descr = socket(AF_INET, SOCK_STREAM, 0)) == -1)
error("error opening stream socket in server", "") ;
/* fill socket data structure */
my_sock_addr.sin_family = AF_INET ;
my_sock_addr.sin_addr.s_addr = INADDR_ANY ;
my_sock_addr.sin_port = PORT_NUMBER ;
/* bind the listen address to the socket */
if (bind(sock_descr, (struct sockaddr *)&my_sock_addr, length) != 0)
error("error binding to stream socket", "") ;
/* start listening at the socket for incoming connections. A maximum
* of MAX_CONN pending connections is allowed.
*/
if (listen(sock_descr, MAX_CONN) != 0)
error("error in listen() call", "") ;
for ( ; ; ) {
/* the following "accept" call will block until a connection
* request arrives. When it is done, it returns a new socket
* descriptor through which client and server can communicate.
* The original socket "sock_descr" is kept for listening to
* further connection requests.
*/
if ((new_sockds = accept(sock_descr, (struct sockaddr *)&client_addr,
&length)) == -1)
error("accept", "") ;
/* create new process to handle client requests */
switch ( fork() ) {
case -1 :
error("fork: can't create new process", "") ;
case 0 : /* child, communicates with client */
server() ;
exit(SUCC) ;
default : /* parent */
/* original process don't need to keep transmission socket */
if (close(new_sockds) == -1)
error("father, close communication socket", "") ;
putchar('\n') ;
/* and keep looping waiting for further connection requests */
}
}
}
/* ------------------------------------------------------------------- */
/* server -- the routine that actually serves incoming client requests */
void server()
{
char *inet_ntoa(); /* returns a pointer to a 'dot' notation Internet addr.*/
char client_name[50], *p = client_name ;
struct hostent *client_info, *gethostbyaddr() ;
char buffer[256] ; /* buffer to read incoming strings */
int nread ;
char message[12] ; /* termination message for client */
(void)strcpy(message, "-- ALL DONE") ;
/* close the listen socket inherited from the father */
if (close(sock_descr) == -1)
error("child: close listen socket", "") ;
/* find out and write client information given the client address
* structure 'client_addr' returned in the preceding 'accept' call.
*/
if ((client_info = gethostbyaddr((char *)&client_addr.sin_addr,
sizeof(struct in_addr), client_addr.sin_family)) == NULL) {
/* since the information is unavailable, use the ascii dot format
* of the Internet address.
*/
(void)strcpy(client_name, "Unknown Host") ;
(void)strcat(client_name, " ") ;
(void)strcat(client_name, inet_ntoa(client_addr.sin_addr)) ;
}
else
p = client_info->h_name ;
printf("'send' process on host '%s' connected to 'receive' server\n", p) ;
/* start receiving requests from the client process */
while ((nread = read(new_sockds, buffer, sizeof buffer)) > 0)
printf("server received: '%s'\n", buffer) ;
if (nread < 0)
error("socket read error", "") ;
/* the server is finished handling client requests, send termination
* message to the client.
*/
if (write(new_sockds, message, sizeof message) < 0)
error("server write error", "") ;
if (close(new_sockds) == -1)
error("close socket", "") ;
}
/* ------------------------------------------------------------------- */
void error(s1, s2) /* print system call error message and exit */
char *s1, *s2 ;
{
extern int errno, sys_nerr ;
extern char *sys_errlist[] ;
fprintf(stderr, "%s %s", s1, s2) ;
if (errno > 0 && errno < sys_nerr)
fprintf(stderr, " (%s)", sys_errlist[errno]) ;
fprintf(stderr, "\n") ;
exit(FAIL) ;
}
/* ------------------------------------------------------------------- */