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