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); }