www.pudn.com > TCPdaytimed.zip > TCPdaytimed.c


/* TCPdaytimed.c :一个使用循环的、面向连接的时间服务的服务器*/ 
 
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
 
#include  
#include  
#include  
#include  
#include  /* close */ 
 
 
#define SUCCESS 0 
#define ERROR   1 
 
#define QLEN 32   /*maxinum connection queue length*/ 
 
extern int            errno; 
 
/* function */ 
void  TCPdaytimed(int fd); 
int  errexit(const char *format, ...); 
int  passiveTCP(const char *service, int qlen); 
 
/*------------------------------------------------------ 
 *  main -Iterative TCP server for DAYTIME service 
 *------------------------------------------------------ 
 */ 
int main (int argc, char *argv[])  
{   
	char       *service = "daytime";  /*service name or port number*/ 
	struct sockaddr_in    fsin;    /*the address of a client*/ 
	unsigned int          alen;    /*length of client's address*/ 
	int                   msock;   /*master server socket*/ 
	int                   ssock;   /*slave server socket*/ 
	 
	switch (argc){ 
		case    1: 
			break; 
		case    2: 
			service = argv[1]; 
			break; 
		default: 
			errexit("usage: TCPdaytimed[port]\n"); 
		} 
	 
	msock = passiveTCP(service, QLEN); 
	 
	while (1) { 
		alen = sizeof(fsin); 
		ssock = accept(msock, (struct sockaddr *)&fsin, &alen); 
		if (ssock < 0)  
			errexit("accept: %s\n", strerror(errno)); 
		TCPdaytimed(ssock); 
		(void) close(ssock); 
	} 
} 
 
/*------------------------------------------------------ 
 *  TCPdaytimed - do TCP DAYTIME protocol 
 *------------------------------------------------------ 
 */ 
void TCPdaytimed(int fd) 
{ 
	char    *pts; /*pointer to time string*/ 
	time_t  now;  /*current time*/ 
	char    *ctime(); 
	 
	(void) time(&now); 
	pts = ctime(&now); 
	(void) write(fd, pts, strlen(pts)); 
} 
 
/*-------------------------------------------------------------- 
 *  passiveTCP - create a passive socket for use in a TCP server 
 *-------------------------------------------------------------- 
 */	 
int passiveTCP(const char *service, int qlen) 
/* 
 *  Arguments: 
 *      service - service associated with the desired port 
 *      qlen    - maxinum server request queue length 
 */ 
{ 
	return passivesock(service, "tcp", qlen); 
} 
 
/*-------------------------------------------------------------- 
 *  passivesock - allocate & bind a server socket using TCP or UDP 
 *-------------------------------------------------------------- 
 */	 
int passivesock(const char *service, const char *transport, int qlen) 
/* 
 *  Arguments: 
 *      service - service associated with the desired port 
 *      transport - transport protocol to user ("tcp" or "udp") 
 *      qlen    - maxinum server request queue length 
 */ 
{ 
	struct servent  *pse;  /*pointer to service information entry*/ 
	struct protoent *ppe;  /*pointer to protocol information entry*/ 
	struct sockaddr_in sin; /*an Internet endpoint address*/ 
	int          s, type;  /*socket descripter and socket type*/ 
	 
	memset(&sin, 0, sizeof(sin)); 
	sin.sin_family = AF_INET; 
	sin.sin_addr.s_addr = INADDR_ANY; 
	 
	/*Map service name to port number*/ 
	if (pse = getservbyname(service, transport)) 
		sin.sin_port = htons(ntohs((unsigned short(pse->s_port) + portbase); 
	else if ((sin.sin_port = htons((unsigned short)atoi(service))) == 0) 
		errexit("can't get \"%s\" service entry\n", service); 
		 
	/*Map protocol name to protocol number*/ 
	if ((ppe = getprotobyname(transport)) == 0) 
		errexit("can't get \"%s\" protocol entry\n", transport); 
	 
	/*Use protocol to choose a socket type*/ 
	if (strcmp(transport, "udp") == 0) 
		type = SOCK_DGRAM; 
	else 
		type = SOCK_STREAM; 
		 
	/*Allocate a socket*/ 
	s = socket(PE_INET, type, ppe->p_proto); 
	if (s < 0) 
		errexit("can't create socket: %s\n", strerror(errno)); 
	 
	/*Bind the socket*/ 
	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) 
		errexit("can't bind to %s port: %s\n", service, strerror(errno)); 
	if (type == SOCK_STREAM && listen(s, qlen) < 0) 
		errexit("can't listen on %s port: %s\n", service, strerror(errno)); 
	return s; 
} 
 
/*------------------------------------------------------ 
 *  errexit - print an error message and exit 
 *------------------------------------------------------ 
 */ 
int errexit(const char * format, ...) 
{ 
	va_list  args; 
	 
	va_start(args, format); 
	vfprintf(stderr, format, args); 
	va_end(args); 
	exit(1); 
}