Iterative Connectionless Servers A connectionless server calls function passiveUDPto create a socket passiveUDP calls passivesock to create a connectionless socket To make it easy to test client and server software passivesock relocates all port values by adding the contents of global integer portbase The importance a If a new version of a client-server application uses the same protocol port numbers as an exist ng, production version, the new software cannot be tested whiTe the production version continues fo execute Using portbase makes it possible to test multiple versions 哈工大计算机学院李全龙 Network Application Development Server Software Design 21
哈工大计算机学院 李全龙 Network Application Development Server Software Design 21 Iterative Connectionless Servers A connectionless server calls function passiveUDP to create a socket passiveUDP calls passivesock to create a connectionless socket To make it easy to test client and server software, passivesock relocates all port values by adding the contents of global integer portbase The importance: If a new version of a client-server application uses the same protocol port numbers as an existing, production version, the new software cannot be tested while the production version continues to execute. Using portbase makes it possible to test multiple versions
passiveUDP / passUDP. cpp-passiveUDP * #include < winsock.h> SOCKET passivesock(const char * const char assiveUDP- create a passive socket for use in a UDP server SOCKET passiveUDP(const char *service) return passivesock (service, " udp",O) 哈工大计算机学院李全龙 Network Application Development Server Software Design 22
哈工大计算机学院 李全龙 Network Application Development Server Software Design 22 passiveUDP /* passUDP.cpp - passiveUDP */ #include <winsock.h> SOCKET passivesock(const char *, const char *, int); /*------------------------------------------------------------------------ * passiveUDP - create a passive socket for use in a UDP server *------------------------------------------------------------------------ */ SOCKET passiveUDP(const char *service) { return passivesock(service, "udp", 0); }
ass/esoc passsock. cpp-passivesock */ #ⅰ nclude< stdlib h #include <string. h> #include <winsock. h> void errexit(const char *, u_short portbase =0:/* port base, for test servers passivesock -allocate bind a server socket using TCP or UDP SOCKET passivesock(const char *service, const char *transport, int qlen Name of a service Name of protocol Length of the connection 哈工大计算机学院李全龙 Network Application Devel request queue(only for TCP)
哈工大计算机学院 李全龙 Network Application Development Server Software Design 23 passivesock /* passsock.cpp - passivesock */ #include <stdlib.h> #include <string.h> #include <winsock.h> void errexit(const char *, ...); u_short portbase = 0; /* port base, for test servers */ /*----------------------------------------------------------------------- * passivesock - allocate & bind a server socket using TCP or UDP *------------------------------------------------------------------------ */ SOCKET passivesock(const char *service, const char *transport, int qlen) Name of a service Name of protocol Length of the connection request queue (only for TCP)
passivel△P struct servent *pse:/ pointer to service information entry struct protoent*ppe; / pointer to protocol information entry * struct sockaddr_in sin: an Internet endpoint address SOCKET S, / socket descriptor int type; socket type(SOCK_STREAM, SOCK_DGRAM)*/ memset (&sin, 0, sizeof(sin)) sinsin_family AF_INET: sin, sin addr s addr INADDR ANy Map service name to port number * if pse getservbyname(service, transport)) sin sin_port tons(ntohs((u_short)pse->s_port) portbase). else if((sinsin_port tons((u_shortatoi(service)==0) errexit("can't get \"%s\"service entry\n", service) 哈工大计算机学院李全龙 Network Application Development Server Software Design 24
哈工大计算机学院 李全龙 Network Application Development Server Software Design 24 passiveUDP { struct servent *pse; /* pointer to service information entry */ struct protoent *ppe; /* pointer to protocol information entry */ struct sockaddr_in sin;/* an Internet endpoint address */ SOCKET s; /* socket descriptor */ int type; /* socket type (SOCK_STREAM, SOCK_DGRAM)*/ 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((u_short)pse->s_port) + portbase); else if ( (sin.sin_port = htons((u_short)atoi(service))) == 0 ) errexit("can't get \"%s\" service entry\n", service);
passiveUDP Map protocol name to protocol number * if ((ppe getprotobyname(transport))==O) errexit("can't get \"%5\protocol entry\n", transport) se protocol to choose a socket type if(strcmp(transport, udp")==O) type= SOCK_DGRAM: else type= SOCKSTREAM: / Allocate a socket*/ s= socket(PF_INET, type, ppe->p_proto) if (s== INVALID_ SOCKET) errexitc'can't create socket: %d \n",GetLastErroro) / Bind the socket * if(bind (s, (struct sockaddr *)&sin, sizeof (sin))==SOCKET_ERROR errexit("can t bind to %os port: %od \n, service, GetLastError 0) if (type = SOCk_StrEAM & listen(s, qlen)== SOCKET_ERROR errexitc"can t listen on %s port: %d\n",service GetLastErroro) return s: 哈工大计算机学院李全龙 Network Application Development Server Software Design 25
哈工大计算机学院 李全龙 Network Application Development Server Software Design 25 passiveUDP /* 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(PF_INET, type, ppe->p_proto); if (s == INVALID_SOCKET) errexit("can't create socket: %d\n", GetLastError()); /* Bind the socket */ if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR) errexit("can't bind to %s port: %d\n", service, GetLastError()); if (type == SOCK_STREAM && listen(s, qlen) == SOCKET_ERROR) errexit("can't listen on %s port: %d\n", service, GetLastError()); return s;}