Wyv9 ?Dy ù ? C Network Application Development Server Software Design 1 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 Wyv9 ?Dy ù ? C Network Application Development Server Software Design 2 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 Wyv9 ?Dy ù ? C Network Application Development Server Software Design 3 The conceptual server algorithm ? Each server follows a simple algorithm ? Creates a socket ? Binds port ? Enters infinite loop ? Accepts request ? Processes request ? Responses ? But only suffices for only the most trivial services Wyv9 ?Dy ù ? C Network Application Development Server Software Design 4 Concurrent vs. Iterative Servers ? Iterative server ? Process one request at a time ? Unnecessary delays ? Easier to build ? Poor performance ? Concurrent server ? Handles multiple requests at one time ? More difficult to design and build ? Better performance Wyv9 ?Dy ù ? C Network Application Development Server Software Design 5 Connection-oriented vs. Connectionless Servers ? Depend on the application protocol ? Connection-oriented servers ? Advantages: ? Ease of programming ? TCP provides reliability ? Disadvantages: ? Require a separate socket for each connection ? Overhead of 3-way handshaking ? TCP does not send any packets over an idle connection- run out of resources Wyv9 ?Dy ù ? C Network Application Development Server Software Design 6 Connection-oriented vs. Connectionless Servers ? Connectionless servers ? Advantages: ? Do not suffer from the problem of resource depletion ? Can supply broadcast or multicast communication ? Disadvantages: ? Can not depend on underlying transport for reliable delivery ? Application protocols respond for reliability Wyv9 ?Dy ù ? C Network Application Development Server Software Design 7 Optimizing stateless servers ? Consider a connectionless server for file reading ? We find: ? Overhead of opening and closing file ? Clients may read only a dozen bytes in each request ? Clients tend to read files sequentially ? To optimize the performance ? Maintain a small table of file information ? State information Wyv9 ?Dy ù ? C Network Application Development Server Software Design 8 Optimizing stateless servers Filename:X Offset:512 Buffer pointer: Filename:Y Offset:1024 Buffer pointer: Table of information about files clients are using hash(IP addr,port) Buffer for file X starting at byte 512 Buffer for file Y starting at byte 1024 Wyv9 ?Dy ù ? C Network Application Development Server Software Design 9 Optimizing stateless servers ? Improve performance without any penalty? ? Even a small amount of information can cause a server to perform badly when machines, client programs, or networks fail ? Frequent crashes can cause one client to dominate the table by filling it with entries that will never be used ? A programmer must be extremely careful when optimizing a stateless server Wyv9 ?Dy ù ? C Network Application Development Server Software Design 10 Four basic types of servers ? Iterative connectionless ? Iterative connection-oriented ? Concurrent connectionless ? Concurrent connection-oriented ? Iterative servers suffice only for the trivial application protocols ? Iterative servers work best with simple services accessed by a connectionless access protocol Wyv9 ?Dy ù ? C Network Application Development Server Software Design 11 Iterative connection-oriented server algorithm 1. Creating a socket and bind to the well-known address for the service being offered. 2. Place the socket in passive mode, making it ready for use by a server. 3. Accept the next connection request from the socket, and obtain a new socket for the connection. 4. Repeatedly receive a request from the client, formulate a response, and send a reply back to the client according to application-protocol. 5. When finished with a particular client, close the connection and return to step 3 to accept a new connection. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 12 Binding to a well-known address by using INADDR_ANY ? bind uses structure sockaddr_in ? Selecting a specific IP address at which a server will accept connections can cause difficulty ? especially for gateways (routers) ? Special constant: INADDR_ANY ? Wildcard address ? Servers use INADDR_ANY instead a specific IP address Wyv9 ?Dy ù ? C Network Application Development Server Software Design 13 Iterative connectionless server algorithm 1. Creating a socket and bind to the well- known address for the service being offered. 2. Repeatedly receive the next request from the client, formulate a response, and send a reply back to the client according to application-protocol. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 14 Forming a reply address in a connectionless server ? Can not use connect ? Uses an unconnected socket ? Uses sendto to send datagram retcode=sendto(socket,data,length,flags,destaddr,addrlen); unconnected socket address of a buffer that contains data to be sent number of bytes in the buffer Debugging or control options Pointer to a sockaddr_in structure that contains the endpoint address Length of the address structure Wyv9 ?Dy ù ? C Network Application Development Server Software Design 15 Forming a reply address in a connectionless server ? Easy way to obtain address of client ? From source address found in request ? Use recvfrom retcode=recvfrom(socket,buf,length,flags,from,fromlen); a socket to use address of a buffer place next datagram Space available in the buffer Debugging or control options Address of the second buffer place the source address Length of the source address Wyv9 ?Dy ù ? C Network Application Development Server Software Design 16 Concurrent connectionless server algorithm Master 1: Creating a socket and bind to the well- known address for the service being offered. Leaving the socket unconnected. Master 2: Repeatedly call recvfrom to receive the next request from a client, and create a new slave thread to handle the response. Slave 1: Receive a specific request upon creation as well as access to the socket. Slave 2: Form a reply according to the app- protocol and send it back to the client using sendto. Slave 3: Exit(i.e., a slave thread terminates after handling one request) Few connectionless servers have concurrent implementations. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 17 Concurrent connection-oriented server algorithm Master 1: Creating a socket and bind to the well- known address for the service being offered. Leaving the socket unconnected. Master 2: Place the socket in passive mode, making it ready for use by a server. Master 3: Repeatedly call accept to receive the next request from a client, and create a new slave thread to handle the response. Slave 1: Receive a connection request (i.e., socket for the connection) upon creation. Slave 2: Interact with the client using the connection: receive request(s) and send back response(s). Slave 3: Close the connection and exit. The slave thread exits after handling all requests from one client. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 18 Apparent Concurrency using a single thread 1. Creating a socket and bind to the well-known address for the service. Add socket to the list of those on which I/O is possible. 2. Use select to wait for I/O on existing sockets. 3. If original socket is ready, use accept to obtain the next connection, and add the new socket to the list of those on which I/O is possible. 4. If some socket other than the original is ready, use recv to obtain the next request, form response, and use send to send the response back to the client. 5. Continue processing with step 2 above. Wyv9 ?Dy ù ? C 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 Wyv9 ?Dy ù ? C 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 Wyv9 ?Dy ù ? C 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 Wyv9 ?Dy ù ? C 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); } Wyv9 ?Dy ù ? C 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) Wyv9 ?Dy ù ? C 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); Wyv9 ?Dy ù ? C 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;} Wyv9 ?Dy ù ? C Network Application Development Server Software Design 26 Thread Structure for Iterative Connectionless Server server Socket at well-known port used for all communication Server application thread Operating system Wyv9 ?Dy ù ? C Network Application Development Server Software Design 27 An example TIME server /* UDPtimed.cpp - main */ #include <time.h> #include <winsock.h> SOCKET passiveUDP(const char *); void errexit(const char *, ...); #define WINEPOCH 2208988800/* Windows epoch, in UCT secs */ #define WSVERS MAKEWORD(2, 0) /*------------------------------------------------------------------------ * main - Iterative UDP server for TIME service *------------------------------------------------------------------------ */ int main(int argc, char *argv[]) Wyv9 ?Dy ù ? C Network Application Development Server Software Design 28 An example TIME server { struct sockaddr_in fsin; /* the from address of a client */ char *service = "time"; /* service name or port number */ char buf[2048]; /* "input" buffer; any size > 1 packet */ SOCKET sock; /* server socket */ time_t now; /* current time */ int alen; /* from-address length */ WSADATA wsadata; switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: UDPtimed [port]\n");} Wyv9 ?Dy ù ? C Network Application Development Server Software Design 29 An example TIME server if (WSAStartup(WSVERS, &wsadata)) errexit("WSAStartup failed\n"); sock = passiveUDP(service); while (1) { alen = sizeof(fsin); if (recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&fsin, &alen) == SOCKET_ERROR) errexit("recvfrom: error %d\n", GetLastError()); (void) time(&now); now = htonl((u_long)(now + WINEPOCH)); (void) sendto(sock, (char *)&now, sizeof(now), 0, (struct sockaddr *)&fsin, sizeof(fsin)); } return 1; /* not reached */ } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 30 Iterative Connection-oriented Servers ? A connection-oriented server calls function passiveTCP to create a stream socket ? passiveTCP takes two arguments: ? A character string-Nname or number of service ? Length of incoming connection request queue Wyv9 ?Dy ù ? C Network Application Development Server Software Design 31 passiveTCP /* passTCP.cpp - passiveTCP */ #include <winsock.h> SOCKET passivesock(const char *, const char *, int); /*---------------------------------------------------------------------- * passiveTCP - create a passive socket for use in a TCP server *----------------------------------------------------------------------- */ SOCKET passiveTCP(const char *service, int qlen) { return passivesock(service, "tcp", qlen); } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 32 Thread Structure for Iterative Connection-oriented Server server Server application thread Operating system Socket used for Connection requests Socket used for an individual connection Wyv9 ?Dy ù ? C Network Application Development Server Software Design 33 An example DAYTIME server /* TCPdtd.cpp - main, TCPdaytimed */ #include <stdlib.h> #include <winsock.h> #include <time.h> void errexit(const char *, ...); void TCPdaytimed(SOCKET); SOCKET passiveTCP(const char *, int); #define QLEN 5 #define WSVERS MAKEWORD(2, 0) /*------------------------------------------------------------------------ * main - Iterative TCP server for DAYTIME service *------------------------------------------------------------------------ */ void main(int argc, char *argv[]) Wyv9 ?Dy ù ? C Network Application Development Server Software Design 34 An example DAYTIME server { struct sockaddr_in fsin;/* the from address of a client */ char *service = "daytime"; /* service name or port number */ SOCKET msock, ssock; /* master & slave sockets */ int alen; /* from-address length */ WSADATA wsadata; switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPdaytimed [port]\n"); } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 35 An example DAYTIME server if (WSAStartup(WSVERS, &wsadata) != 0) errexit("WSAStartup failed\n"); msock = passiveTCP(service, QLEN); while (1) { alen = sizeof(struct sockaddr); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock == INVALID_SOCKET) errexit("accept failed: error number %d\n", GetLastError()); TCPdaytimed(ssock); (void) closesocket(ssock); } } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 36 An example DAYTIME server /*---------------------------------------------------------------------- * TCPdaytimed - do TCP DAYTIME protocol *----------------------------------------------------------------------- */ void TCPdaytimed(SOCKET fd) { char *pts; /* pointer to time string */ time_t now; /* current time */ (void) time(&now); pts = ctime(&now); (void) send(fd, pts, strlen(pts), 0); } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 37 Closing connections ? Calling closesocket requests a graceful shutdown ? Does not worry about data lost ? The application protocol determines how a server manages TCP connections ? The client must signal completion ? Allowing a client to control connection duration can be dangerous Wyv9 ?Dy ù ? C Network Application Development Server Software Design 38 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 Wyv9 ?Dy ù ? C Network Application Development Server Software Design 39 Concurrent Connection-oriented Servers ? Consider concurrent ECHO ? Iterative VS Concurrent implementation ? Iterative performs poorly ? Concurrent avoids long delay ? Concurrent offers better observed response time Wyv9 ?Dy ù ? C Network Application Development Server Software Design 40 Thread Structure for Concurrent Connection-oriented Server server Server application thread Operating system Socket for Connection requests Socket for individual connection slave 1 slave 2 slave n … Wyv9 ?Dy ù ? C Network Application Development Server Software Design 41 An example concurrent ECHO server /* TCPechod.cpp - main, TCPechod */ #include <stdio.h> #include <winsock.h> #include <process.h> #define QLEN 5 /* maximum connection queue length */ #define STKSIZE 16536 #define BUFSIZE 4096 #define WSVERS MAKEWORD(2, 0) SOCKET msock, ssock; /* master & slave server sockets */ int TCPechod(SOCKET); void errexit(const char *, ...); SOCKET passiveTCP(const char *, int); Wyv9 ?Dy ù ? C Network Application Development Server Software Design 42 An example concurrent ECHO server /*------------------------------------------------------------------------ * main - Concurrent TCP server for ECHO service *------------------------------------------------------------------------ */ int main(int argc, char *argv[]) { char *service = "echo"; /* service name or port number */ struct sockaddr_in fsin; /* the address of a client */ int alen; /* length of client's address */ WSADATA wsadata; switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPechod [port]\n"); } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 43 An example concurrent ECHO server if (WSAStartup(WSVERS, &wsadata) != 0) errexit("WSAStartup failed\n"); msock = passiveTCP(service, QLEN); while (1) { alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock == INVALID_SOCKET) errexit("accept: error number\n", GetLastError()); if (_beginthread((void (*)(void *))TCPechod, STKSIZE, (void *)ssock) < 0) { errexit("_beginthread: %s\n", strerror(errno)); } } return 1; /* not reached */} Wyv9 ?Dy ù ? C Network Application Development Server Software Design 44 An example concurrent ECHO server /*------------------------------------------------------------------------ * TCPechod - echo data until end of file *------------------------------------------------------------------------ */ int TCPechod(SOCKET fd) { char buf[BUFSIZE]; int cc; cc = recv(fd, buf, sizeof buf, 0); while (cc != SOCKET_ERROR && cc > 0) { if (send(fd, buf, cc, 0) == SOCKET_ERROR) { fprintf(stderr, "echo send error: %d\n", GetLastError()); break;} cc = recv(fd, buf, sizeof buf, 0);} if (cc == SOCKET_ERROR) fprintf(stderr, "echo recv error: %d\n", GetLastError()); closesocket(fd); return 0;} Wyv9 ?Dy ù ? C Network Application Development Server Software Design 45 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 Wyv9 ?Dy ù ? C Network Application Development Server Software Design 46 Singly-Threaded, Concurrent Servers (TCP) ? Data-driven processing in a server ? For applications where I/O dominates the cost of preparing a response to a request, a server can use asynchronous I/O to provide apparent concurrency ? Arrange for a single server thread to keep TCP connections open to multiple clients, and have the server handle a given connection when data arrives ? The server uses the arrival of data to trigger processing ? Consider previous concurrent ECHO server ? Slave thread spends most time blocked in a call to recv ? Concurrent servers that require little processing time per request often behave in a sequential manner ? Data-driven processing with a single thread ? A single thread can perform the same task Wyv9 ?Dy ù ? C Network Application Development Server Software Design 47 Thread Structure for A Singly- threaded Server server Server application thread Operating system Socket for Connection requests Socket for individual connection … Wyv9 ?Dy ù ? C Network Application Development Server Software Design 48 Thread Structure for A Singly- threaded Server ? A single thread server must perform the duties of both the master and slave threads ? The server passes the set of socket descriptors as argument to select ? select returns bit mask that specifies which of the descriptors in the set is ready ? The server uses the order in which descriptors become ready to decide how to proceed ? The server uses the descriptors to distinguish between master and slave operations Wyv9 ?Dy ù ? C Network Application Development Server Software Design 49 An example Singly-threaded ECHO server /* TCPmechd.cpp - main, echo */ #include <winsock.h> #include <string.h> #define QLEN 5 /* maximum connection queue length */ #define BUFSIZE 4096 #define WSVERS MAKEWORD(2, 0) void errexit(const char *, ...); SOCKET passiveTCP(const char *, int); int echo(SOCKET); Wyv9 ?Dy ù ? C Network Application Development Server Software Design 50 An example Singly-threaded ECHO server /*------------------------------------------------------------------------ * main - Concurrent TCP server for ECHO service *------------------------------------------------------------------------ */ void main(int argc, char *argv[]) { char *service = "echo";/* service name or port number */ struct sockaddr_in fsin;/* the from address of a client*/ SOCKET msock; /* master server socket */ fd_set rfds; /* read file descriptor set */ fd_set afds; /* active file descriptor set */ int alen; /* from-address length */ WSADATA wsdata; unsigned int fdndx; Wyv9 ?Dy ù ? C Network Application Development Server Software Design 51 An example Singly-threaded ECHO server switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPmechod [port]\n"); } if (WSAStartup(WSVERS, &wsdata) != 0) errexit("WSAStartup failed\n"); msock = passiveTCP(service, QLEN); FD_ZERO(&afds); FD_SET(msock, &afds); Wyv9 ?Dy ù ? C Network Application Development Server Software Design 52 An example Singly-threaded ECHO server while (1) { memcpy(&rfds, &afds, sizeof(rfds)); if (select(FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) == SOCKET_ERROR) errexit("select error: %d\n", GetLastError()); if (FD_ISSET(msock, &rfds)) { SOCKET ssock; alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock == INVALID_SOCKET) errexit("accept: error %d\n", GetLastError()); FD_SET(ssock, &afds);} Wyv9 ?Dy ù ? C Network Application Development Server Software Design 53 An example Singly-threaded ECHO server for (fdndx=0; fdndx<rfds.fd_count; ++fdndx){ SOCKET fd = rfds.fd_array[fdndx]; if (fd != msock && FD_ISSET(fd, &rfds)) if (echo(fd) == 0) { (void) closesocket(fd); FD_CLR(fd, &afds); } } } } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 54 An example Singly-threaded ECHO server /*------------------------------------------------------------------------ * echo - echo one buffer of data, returning byte count *------------------------------------------------------------------------ */ int echo(SOCKET fd) { char buf[BUFSIZE]; int cc; cc = recv(fd, buf, sizeof buf, 0); if (cc == SOCKET_ERROR) errexit("echo recv error %d\n", GetLastError()); if (cc && send(fd, buf, cc, 0) == SOCKET_ERROR) errexit("echo send error %d\n", GetLastError()); return cc; } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 55 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 Wyv9 ?Dy ù ? C Network Application Development Server Software Design 56 Multiprotocol Servers ? Motivation for reducing the number of servers ? In most cases, a given server handles requests for one particular service accessed through one particular transport protocol ? The chief advantage of using separate server for each protocol lies in control ? The chief disadvantage lies in replication and use of resources ? Multiprotocol server design ? A single thread that uses asynchronous I/O Wyv9 ?Dy ù ? C Network Application Development Server Software Design 57 Thread Structure for multiprotocol Server server Server application thread Operating system Socket for UDP requests Socket for TCP conn. requests … Socket for a TCP connection Wyv9 ?Dy ù ? C Network Application Development Server Software Design 58 An example multiprotocol DAYTIME server /* daytimed.cpp - main, daytime */ #include <stdio.h> #include <time.h> #include <winsock.h> void daytime(char buf[]); void errexit(const char *, ...); SOCKET passiveTCP(const char *, int); SOCKET passiveUDP(const char *); #define WSVERS MAKEWORD(2, 0) #define QLEN 5 #define LINELEN 128 Wyv9 ?Dy ù ? C Network Application Development Server Software Design 59 An example multiprotocol DAYTIME server /*------------------------------------------------------------------------ * main - Iterative server for DAYTIME service *------------------------------------------------------------------------ */ void main(int argc, char *argv[]) { char *service = "daytime"; /* service name or port number */ char buf[LINELEN+1]; /* buffer for one line of text */ struct sockaddr_in fsin;/* the request from address */ int alen; /* from-address length */ SOCKET tsock; /* TCP master socket */ SOCKET usock; /* UDP socket */ fd_set rfds; /* readable file descriptors */ int rv; WSADATA wsadata; Wyv9 ?Dy ù ? C Network Application Development Server Software Design 60 An example multiprotocol DAYTIME server switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: daytimed [port]\n"); } if (WSAStartup(WSVERS, &wsadata) != 0) errexit("WSAStartup failed\n"); tsock = passiveTCP(service, QLEN); usock = passiveUDP(service); FD_ZERO(&rfds); Wyv9 ?Dy ù ? C Network Application Development Server Software Design 61 An example multiprotocol DAYTIME server while (1) { FD_SET(tsock, &rfds); FD_SET(usock, &rfds); if (select(FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) == SOCKET_ERROR) errexit("select error: %d\n", GetLastError()); if (FD_ISSET(tsock, &rfds)) { SOCKET ssock; /* TCP slave socket */ alen = sizeof(fsin); ssock = accept(tsock, (struct sockaddr *)&fsin, &alen); if (ssock == INVALID_SOCKET) errexit("accept failed: error %d\n", GetLastError()); daytime(buf); Wyv9 ?Dy ù ? C Network Application Development Server Software Design 62 An example multiprotocol DAYTIME server (void) send(ssock, buf, strlen(buf), 0); (void) closesocket(ssock); } if (FD_ISSET(usock, &rfds)) { alen = sizeof(fsin); rv = recvfrom(usock, buf, sizeof(buf), 0, (struct sockaddr *)&fsin, &alen); if (rv == SOCKET_ERROR) errexit("recvfrom: error number %d\n", GetLastError()); daytime(buf); (void) sendto(usock, buf, strlen(buf), 0, (struct sockaddr *)&fsin, sizeof(fsin)); } } } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 63 An example multiprotocol DAYTIME server /*------------------------------------------------------------------------ * daytime - fill the given buffer with the time of day *------------------------------------------------------------------------ */ void daytime(char buf[]) { time_t now; (void) time(&now); sprintf(buf, "%s", ctime(&now)); } Concurrent multiprotocol servers? Wyv9 ?Dy ù ? C Network Application Development Server Software Design 64 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 Wyv9 ?Dy ù ? C Network Application Development Server Software Design 65 Multiservice Servers ? Consolidating servers ? In most cases, programmers design an individual server to handle each service ? Consolidating many services into a single server reduces the total code required Wyv9 ?Dy ù ? C Network Application Development Server Software Design 66 A Connectionless Multiservice Server design server Server application thread Operating system Master Sockets (one for each service being offered) … Wyv9 ?Dy ù ? C Network Application Development Server Software Design 67 A Connection-oriented Multiservice Server design master Server application thread Operating system Master Sockets (one for each Service offered) … Socket for one individual connection Wyv9 ?Dy ù ? C Network Application Development Server Software Design 68 A Concurrent Connection-oriented Multiservice Server design master Server application thread Operating system Master Sockets (one for each Service offered) Socket for individual slave connections slave 1 slave n … … How to design a singly-threaded, multiservice server? Wyv9 ?Dy ù ? C Network Application Development Server Software Design 69 Invoking separate programs from a Multiservice Server master Server processes Operating system Master Sockets (one for each Service offered) Socket for individual slave connections slave 1 slave n … … In a multiservice server, the Windows CreateProcess call makes it possible to separate the code that handles an individual service from the code that manages initial requests from clients. CreateProcess used Wyv9 ?Dy ù ? C Network Application Development Server Software Design 70 Multiservice, Multiprotocol Designs ? Multiprotocol, multiservice design is possible ? The server can manage UDP and TCP sockets for some or all of the services it offers ? Many networking experts use the term super server to refer to a multiservice, multiprotocol server Wyv9 ?Dy ù ? C Network Application Development Server Software Design 71 An example Multiservice server /* superd.cpp - main, doTCP */ #include <process.h> #include <winsock.h> #define UDP_SERV 0 #define TCP_SERV 1 struct service { char *sv_name; char sv_useTCP; SOCKET sv_sock; void (*sv_func)(SOCKET); }; void TCPechod(SOCKET), TCPchargend(SOCKET), TCPdaytimed(SOCKET), TCPtimed(SOCKET); Wyv9 ?Dy ù ? C Network Application Development Server Software Design 72 An example Multiservice server SOCKET passiveTCP(const char *, int); SOCKET passiveUDP(const char *); void errexit(const char *, ...); void doTCP(struct service *); struct service svent[ ] = { { "echo", TCP_SERV, INVALID_SOCKET, TCPechod }, { "chargen", TCP_SERV, INVALID_SOCKET, TCPchargend }, { "daytime", TCP_SERV, INVALID_SOCKET, TCPdaytimed }, { "time", TCP_SERV, INVALID_SOCKET, TCPtimed }, { 0, 0, 0, 0 }, }; #define WSVERS MAKEWORD(2, 0) #define QLEN 5 #define LINELEN 128 extern u_short portbase; /* from passivesock() */ Wyv9 ?Dy ù ? C Network Application Development Server Software Design 73 An example Multiservice server /*------------------------------------------------------------------------ * main - Super-server main program *------------------------------------------------------------------------ */ void main(int argc, char *argv[ ]) { struct service *psv; /* service table pointer */ fd_set afds, rfds; /* readable file descriptors*/ WSADATA wsdata; switch (argc) { case 1: break; case 2: portbase = (u_short) atoi(argv[1]); break; default: errexit("usage: superd [portbase]\n");} Wyv9 ?Dy ù ? C Network Application Development Server Software Design 74 An example Multiservice server if (WSAStartup(WSVERS, &wsdata)) errexit("WSAStartup failed\n"); FD_ZERO(&afds); for (psv = &svent[0]; psv->sv_name; ++psv) { if (psv->sv_useTCP) psv->sv_sock = passiveTCP(psv->sv_name, QLEN); else psv->sv_sock = passiveUDP(psv->sv_name); FD_SET(psv->sv_sock, &afds); } while (1) { memcpy(&rfds, &afds, sizeof(rfds)); if (select(FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) == SOCKET_ERROR) errexit("select error: %d\n", GetLastError()); Wyv9 ?Dy ù ? C Network Application Development Server Software Design 75 An example Multiservice server for (psv=&svent[0]; psv->sv_name; ++psv) { if (FD_ISSET(psv->sv_sock, &rfds)) { if (psv->sv_useTCP) doTCP(psv); else psv->sv_func(psv->sv_sock); } } } } /*------------------------------------------------------------------------ * doTCP - handle a TCP service connection request *------------------------------------------------------------------------ */ Wyv9 ?Dy ù ? C Network Application Development Server Software Design 76 An example Multiservice server void doTCP(struct service *psv) { struct sockaddr_in fsin; /* the request from address */ int alen; /* from-address length */ SOCKET ssock; alen = sizeof(fsin); ssock = accept(psv->sv_sock, (struct sockaddr *)&fsin, &alen); if (ssock == INVALID_SOCKET) errexit("accept: %d\n", GetLastError()); if (_beginthread((void (*)(void *))psv->sv_func, 0, (void *)ssock) == (unsigned long) -1) errexit("_beginthread: %s\n", strerror(errno)); } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 77 An example Multiservice server /* sv_funcs.cpp - TCPechod, TCPchargend, TCPdaytimed, TCPtimed */ #include <stdio.h> #include <time.h> #include <winsock.h> #define BUFFERSIZE 4096 /* max read buffer size*/ void TCPechod(SOCKET), TCPchargend(SOCKET), TCPdaytimed(SOCKET), TCPtimed(SOCKET); void errexit(const char *, ...); Wyv9 ?Dy ù ? C Network Application Development Server Software Design 78 An example Multiservice server /*------------------------------------------------------------------------ * TCPecho - do TCP ECHO on the given socket *------------------------------------------------------------------------ */ void TCPechod(SOCKET fd) { char buf[BUFFERSIZE]; int cc; while (cc = recv(fd, buf, sizeof buf, 0)) { if (cc == SOCKET_ERROR) errexit("echo recv: errnum %d\n", GetLastError()); if (send(fd, buf, cc, 0) == SOCKET_ERROR) errexit("echo send: errnum %d\n", GetLastError()); } closesocket(fd);} Wyv9 ?Dy ù ? C Network Application Development Server Software Design 79 An example Multiservice server #define LINELEN 72 /*------------------------------------------------------------------------ * TCPchargend - do TCP CHARGEN on the given socket *-----------------------------------------------------------------------*/ void TCPchargend(SOCKET fd) { char c, buf[LINELEN+2]; /* print LINELEN chars + \r\n */ c = ' '; buf[LINELEN] = '\r'; buf[LINELEN+1] = '\n'; while (1) { int i; for (i=0; i<LINELEN; ++i) { buf[i] = c++; if (c > '~') c = ' '; } if (send(fd, buf, LINELEN+2, 0) == SOCKET_ERROR) break; } closesocket(fd);} Wyv9 ?Dy ù ? C Network Application Development Server Software Design 80 An example Multiservice server /*------------------------------------------------------------------------ * TCPdaytimed - do TCP DAYTIME protocol *------------------------------------------------------------------------ */ void TCPdaytimed(SOCKET fd) { char buf[LINELEN]; time_t now; (void) time(&now); sprintf(buf, "%s", ctime(&now)); (void) send(fd, buf, strlen(buf), 0); closesocket(fd); } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 81 An example Multiservice server #define WINEPOCH 2208988800 /* Windows epoch, in UCT secs */ /*------------------------------------------------------------------------ * TCPtimed - do TCP TIME protocol *---------------------------------------------------------------------- */ void TCPtimed(SOCKET fd) { time_t now; (void) time(&now); now = htonl((u_long)(now + WINEPOCH)); (void) send(fd, (char *)&now, sizeof(now), 0); closesocket(fd); } Wyv9 ?Dy ù ? C Network Application Development Server Software Design 82 Static and Dynamic Server Configuration ? Many systems supply the skeleton of a super server to which system administrators can add additional services. ? Super servers are often configurable. ? Two types of configuration are possible: ? Static ? Dynamic ? A super server that can be reconfigured dynamically is flexible Wyv9 ?Dy ù ? C Network Application Development Server Software Design 83 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 Wyv9 ?Dy ù ? C Network Application Development Server Software Design 84 Choosing Between an iterative and a concurrent design ? Two kinds of server design: iteratively and concurrently ? The choice between iterative and concurrent implementation is fundamental because it influences: ? Entire program structure ? Response time ? Ability of multiple requests handling ? Choosing can be difficult, because rapidly change of: ? User demands ? Processing speeds ? Communication capabilities ? Most designers extrapolate from recent trends when making a choice. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 85 Level of concurrency ? One of the details of concurrent server implementation ? Level of concurrency: total number of processes or threads the server has running at a given time ? The level of concurrency varies over time ? Care about the maximum level of concurrency not any given instant ? Only a few of the designs specify the maximum level of concurrency ? Most of the designs permit the master to create threads as needed Wyv9 ?Dy ù ? C Network Application Development Server Software Design 86 Level of concurrency ? A practical server cannot handle arbitrarily many connections ? Each implementation of TCP places a bound on the number of active connections possible ? Each OS places a bound on the number of processes or threads available ? When server reaches one of theses limits, the system will deny requests from functions like _beginthread or CreateProcess ? To increase server flexibility, many programmers avoid placing a fixed upper bound on the maximum level of concurrency ? Servers that do not bound concurrency are at risk Wyv9 ?Dy ù ? C Network Application Development Server Software Design 87 Demand-Driven Concurrency ? Also request-driven concurrency ? Incoming requests to trigger an increase in concurrency- demand driven ? Servers that increase concurrency on demand may seem optimal ? Do not use system resources unless needed ? Demand- driven servers do not use resources unnecessarily ? Demand- driven servers provide low observed response times Wyv9 ?Dy ù ? C Network Application Development Server Software Design 88 Cost of concurrency ? Must consider the cost of concurrency as well as its benefits ? The level of concurrency at any instant reflects the number of requests the server has received but not finished processing ? Overhead and delay ? Creating a new thread for each request can be expensive ? Can take considerable time ? Creating a thread consumes system resources Wyv9 ?Dy ù ? C Network Application Development Server Software Design 89 Small delay can matter ? Does the short delay incurred while creating a new process or thread matter? ? For example: Consider the situation of the time to handle a request is less than the time to create a new thread ? Tow requests arrive at a burst Create slave 1 Create slave 1 Handle req. 1 Handle req. 2 concurrent 0c 2c 2c+p Handle req. 1 Handle req. 2 iterative 0p 2p Wyv9 ?Dy ù ? C Network Application Development Server Software Design 90 Small delay can matter ? Concurrent version requires an average of 3c/2+p time units per request ? iterative version requires an average of 3p/2 time units per request ? Iterative server exhibits lower average delay Create slave 1 Create slave 1 Handle req. 1 Handle req. 2 concurrent 0c 2c 2c+p Handle req. 1 Handle req. 2 iterative 0p 2p Wyv9 ?Dy ù ? C Network Application Development Server Software Design 91 Small delay can matter ? The small additional delay can be significant if one considers continuous operation of a server under heavy load ? Small delays in the server affect the observed response time but not the overall throughput. ? If a burst of requests arrives at or near the same time, protocol software will enqueue them. ? In the long term, extra delays can cause requests to be lost. ? Few designers use concurrent servers when the cost of creating a thread exceeds the cost of processing Wyv9 ?Dy ù ? C Network Application Development Server Software Design 92 Thread preallocation ? A straightforward technique- preallocating concurrent threads ? A designer programs the master server to create N slave threads when it begins execution. ? Each thread uses facilities available in the OS to wait for a request to arrive. ? When a request arrives, one of the waiting slave threads begins execution and handles the request. ? When it finishes handling a request, the slave does not terminate. ? The chief advantage is lower OS overhead. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 93 Thread preallocation ? Preallocation techniques ? The details of preallocation depend on underlying OS and the type of concurrency. ? In Windows: ? Preallocated threads can use shared memory to coordinate with the master. ? Preallocated processes often rely on message passing facilities. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 94 Thread preallocation ? Preallocation techniques ? In systems do not offer shared memory ? preallocation can use socket functions to coordinate. ? Socket functions can be used to coordinate concurrency in systems that allow a child thread or process to inherit access to socket descriptors that the parent has opened.a ? A master server opens the necessary socket before it preallocates any slave. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 95 Preallocation in a connection- oriented server ? Level of concurrency depends on the number of active connections. ? In most systems, the socket functions provide mutual exclusion for multiple slaves that all attempt to accept a connection from the same socket. ? Each slave calls accept. ? All slaves inherit access to the socket for the well-known port. ? The master has no role after it preallocates the slaves. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 96 Preallocation in a connection- oriented server master Server application thread Operating system socket for connection requests socket for individual connections (created by accept) slave 1 slave n slave 1 Wyv9 ?Dy ù ? C Network Application Development Server Software Design 97 Preallocation in a connectionless server ? Level of concurrency depends on the number of requests that arrive. ? Windows permits a connectionless server to preallocate just like a connection-oriented server. ? Each slave shares access to socket for the well-known port. ? The master for the connectionless case has little to do after it ? Opens the socket for the well-known port, ? Preallocates the slaves. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 98 Preallocation in a connectionless server master Server application thread Operating system socket for well- known port slave 1 slave n slave 1 Wyv9 ?Dy ù ? C Network Application Development Server Software Design 99 Preallocation, Bursty Traffic, NFS, Multiprocessor ? Most implementation of UDP do not provide large queue for arriving datagrams ? Bursts of incoming can easily overrun a queue ? Bursts of traffic can cause loss ? Overrun is especially difficult because UDP often resides in OS ? Application programmers cannot always modify it easily ? Application programmers can preallocate slave threads, ? The preallocation is usually sufficient to eliminate loss. ? Many NFS use preallocation to avoid loss. ? Preallocation on a multiprocessor permits the designer to relate the level of concurrency in a server to the hardware’s capability. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 100 Delayed thread allocation ? Preallocation can improve efficiency, but does not solve all problem. ? In some circumstances efficiency can be improved by using the opposite approach: Delaying slave allocation ? Thread creation takes time and ? Add overhead to OS ? Add overhead to networking code ? Concurrency will lower delay if the cost of creating a thread is smaller than the cost of processing a request. ? A programmer cannot always know how the costs will compare ? The time required may depend on the request Wyv9 ?Dy ù ? C Network Application Development Server Software Design 101 Delayed thread allocation ? The programmer cannot know whether an error will be found quickly. ? How can designer optimize delay and throughput? ? Answer lies in a technique: delayed concurrency ? Instead of choosing an iterative or concurrent design. ? Allow a server to measure processing cost and choosing between iterative handling or concurrent handling dynamically. ? Servers usually estimate processing cost by measuring elapsed time. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 102 Delayed thread allocation ? Master server set a timer for a receiving request ? Processing the request iteratively ? If the server finishes processing before timer expires ? The server cancels the timer. ? Otherwise ? The server creates a slave and allows it to handle the request. ? This way, allows the master to ? Check for errors ? Handle short requests before ? Creates a thread or ? Switches context Wyv9 ?Dy ù ? C Network Application Development Server Software Design 103 The uniform for both techniques ? In common for both techniques? ? They share much in common: ? The same conceptual principle: to improve the performance of some concurrent servers ? By detaching the level of server concurrency from the number of concurrently active requests, the designer can gain flexibility and improve server efficiency. ? Both techniques can be combined. ? A server can begin with no preallocation, but using delayed allocation. ? The biggest problem with combined system is how to control concurrency 104 Raw socket programming Wyv9 ?Dy ù ? C Network Application Development Server Software Design 105 Row Socket Programming(1) ? Raw socket support few functions can’t be implemented through Stream (TCP) or Datagram (UDP) socket. ? Raw socket can: ? Access ICMP and IGMP packets; ? Operate IP datagram not processed by OS kernel; ? Create self-formatted IP header; ? Develop high-level protocols based on IP. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 106 ? Create a raw socket by setting 2 nd parameters to SOCK_RAW in function socket(); ? 3 rd parameters is used to define protocols used by the socket. ? If proto=0, means this raw socket can receive any IP datagram from OS kernel. Row Socket Programming(2) desc = socket(protofamily,type,proto); Wyv9 ?Dy ù ? C Network Application Development Server Software Design 107 ? For example: Row Socket Programming(3) #include <netinet/in.h> …… int sockfd; sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); …… ? A raw socket to access ICMP. Wyv9 ?Dy ù ? C Network Application Development Server Software Design 108 ? If want to create your own IP header, you can set IP_HDRINCL option over raw socket. ? Such as: Row Socket Programming(4) int on=1; If(setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on))<0){ fprintf(stderr,”setsockopt IP_HDRINCL erroe.\n”; exit(1); } …… Wyv9 ?Dy ù ? C Network Application Development Server Software Design 109 ? Function bind() can associate local IP address to raw socket. (if IP_HDRINCL set bind() invalid) ? Function connect() can associate remote IP address to raw socket. ? send(), sendto(),write() can be used to send data. ? If IP_HDRINCL set, IP header must be created by yourself. Row Socket Programming(5) Wyv9 ?Dy ù ? C Network Application Development Server Software Design 110 ? OS kernel never send UDP or TCP segments to raw socket. ? Most ICMP datagrams will be sent to suitable raw socket. ? All other packets processed by OS kernel will be sent to suitable raw socket. ? All IP packets that unrecognized by kernel sent to suitable raw socket. ? recvfrom() used to receive packets from raw socket. Row Socket Programming(6) Wyv9 ?Dy ù ? C Network Application Development Server Software Design 111 Summary We have Learned: ? Algorithm and issues ? Iterative servers ? Concurrent, connection-oriented servers ? Singly-threaded, concurrent servers ? Multiprotocol servers ? Multiservice servers ? Uniform, efficient management of server concurrency ? Introduction to raw socket programming