Chapter 4: Server Software Design Creating a Passive Socket Chapter gae a Algorithm and issues Use procedures to hide the details a Iterative servers Two high-level procedures a Concurrent connection-oriented passrveUDP servers a Singly-threaded, concurrent The low-level procedure: passivesock servers Multiprotocol servers Multiservice servers Uniform, efficient management of server concurrency Iterative Connectionless Servers passiveUDP A connectionless server calls function passiveUDPto passUDP. cpp-passiveUDP*/ create a socke CossivelDP calls passivesock to create a #include <winsock. hp connectionless socket SOCKET passivesock(const char*, const char * int): To maks it keaeyototst c bent and s rver software c passiveUDP-create a passive socket for use in a UDP The importance soffware cannot be tested while the production passiveUDP(const char * service continues to execute Using portbase makes it possible to test multiple turn passivesock(service, "udp", o versions passivesock passiveUDP void errexit(const char*,: soler sockaddr_n sinc /. an Internet endpoint address entry u_short portbase =0:/ port base, for test servers type: /socket type(SOCK-STREAM, SOCK_DGRAM)- passivesock-allocate bind a server socket using ToP or UDP nsin port hons(ntohs((u.)pse-s_port portbase: else if ((sin, inport Name of a service errexitccan't get \7s\"service entry\n, service):4 哈工大计算机学院 李全龙 Network Application Development Server Software Design 19 Chapter 4: Server Software Design Chapter goal: Algorithm and issues Iterative servers Concurrent, connection-oriented servers Singly-threaded, concurrent servers Multiprotocol servers Multiservice servers Uniform, efficient management of server concurrency 哈工大计算机学院 李全龙 Network Application Development Server Software Design 20 Creating a Passive Socket Use procedures to hide the details Two high-level procedures: passiveUDP passiveTCP The low-level procedure: passivesock 哈工大计算机学院 李全龙 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 哈工大计算机学院 李全龙 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); } 哈工大计算机学院 李全龙 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) 哈工大计算机学院 李全龙 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);