Title: TDC561%20Network%20Programming
1TDC561 Network Programming
- Week 4
- Client/Server Design Approaches
- Case Study Using Sockets
- A Client Server Application of Network
Performance Management - presentation prepared with the help of
- Dale Knudson PhD, Lucent Technologies
2References
- Douglas Comer, David Stevens, Internetworking
with TCP/IP Client-Server Programming, Volume
III (BSD Unix and ANSI C), 2nd edition, 1996
(ISBN 0-13-260969-X) - Chap. 2, 8
- W. Richard Stevens, Network Programming
Networking API Sockets and XTI, Volume 1, 2nd
edition, 1998 (ISBN 0-13-490012-X) - Chap. 7 (partial), 27 (partial), 16.1-16.3
(partial)
3Server Design
Iterative Connectionless
Iterative Connection-Oriented
Concurrent Connection-Oriented
Concurrent Connectionless
4Concurrent vs. Iterative
- Concurrent
- Large or variable size requests
- Harder to program
- Typically uses more system resources
- Iterative
- Small, fixed size requests
- Easy to program
5Connectionless vs. Connection-Oriented
- Connection-Oriented
- Easy to program
- Transport protocol handles the tough stuff.
- Requires separate socket for each connection.
- Connectionless
- Less overhead
- No limitation on number of clients
6Statelessness
- State Information that a server maintains about
the status of ongoing client interactions. - Issues with Statefullness
- Clients can go down at any time.
- Client hosts can reboot many times.
- The network can lose messages.
- The network can duplicate messages.
- Example
- Connectionless servers that keep state
information must be designed carefully - Messages can be duplicated
7Concurrent Server Design Alternatives
- One child per client
- Single Process Concurrency (AKA
Pseudo-Concurrency or - Apparent Concurrency)
- Pre-forking multiple processes
- Spawn one thread per client
- Pre-threaded Server
will be discussed in a future lecture
8One child per client
- Traditional Unix server
- TCP after call to accept(), call fork().
- UDP after recvfrom(), call fork().
- Each process needs only a few sockets.
- Small requests can be serviced in a small amount
of time. - Parent process needs to clean up after children
(call wait() ).
9Discussion Stevens Example Concurrency using
fork() 1/3
- / Code fragment that uses fork() and signal()
- to implement concurrency /
- / include and define statements section /
- void signal_handler(int sig)
- int status
- wait(status) / awaits child process to exit
- therefore allows child to
terminate, - and to transit from ZOMBIE to
- NORMAL TEMINATION (END) state
- /
- signal(SIGCHLD,signal_handler)
- / restarts signal handler /
10Discussion Stevens Example Concurrency using
fork() 2/3
- main(int argc, char argv)
-
- / Variable declaration section /
- / The calls socket(), bind(), and listen() /
- signal(SIGCHLD,signal_handler)
- while(1) / infinite accept() loop /
- newfd accept(sockfd,(struct sockaddr
)theiraddr,sinsize) - if (newfd lt 0)
- / error in accept() /
- if (errno EINTR)
- continue
- else
- perror("accept")
- exit(-1)
-
See previous slide
11Discussion Stevens Example Concurrency using
fork() 3/3
- / successfully accepted a new client connection
newfd gt0 / - switch (fork())
- case -1 / fork() error /
- perror("fork")
- exit(-1)
- case 0 / child handles request /
- close(sockfd)
- / read msg and form a response /
- / send response back to the client /
- close(newfd)
- exit(-1) / exit() sends by default SIGCHLD to
parent / - default / parent returns to wait for another
request / - close(newfd)
- / end switch /
- / end while(1) /
-
12Discussion Single Process Concurrency 1/2
- main(int argc, char argv)
-
- / various declarations /
- int result
- fd_set readfds, testfds
- / socket(), bind(), listen() /
- / inititialization of the fd set
- FD_ZERO(readfds)
- / add listening socket sockfd to the reading set
/ - FD_SET(sockfd,readfds)
- while(1)
- int fd
- testfds readfds
- result select(FD_SETSIZE, testfds, NULL, NULL,
NULL) - / error check for select /
13Discussion Single Process Concurrency 2/2
- for (fd 0 fd lt FD_SETSIZE fd)
- if (FD_ISSET(fd,testfds)) / find activated
socket fd / - if (fd sockfd) / gt New connection /
- newfd accept(sockfd,(struct sockaddr
)theiraddr,sinsize) - FD_SET(newfd,readfds) / update file descriptor
set with newfd / -
- else / gt request from old'' connection /
- / call read() and handle request
- from old connection using fd /
- close(fd)
- FD_CLR(fd,readfds) / remove fd when
connection finished / - / else /
- / end if (FD_ISSET() /
- / end for ( ) /
- / end while(1) /
- return 1
14- OAMP - Operations, Administration, Maintenance
and Provisioning - ITU Categories
- (International Telecommunications Union)
- Configuration Management (CM)
- Accounting Management (AM)
- Fault Management (FM)
- Performance Management (PM)
- Security Management (SM)
15Performance Management
Custom Reports
PM report (one per hour)
OSS NM
Wireless Switch
ftp
What if you want the data more frequently?
OSS NM Operation Support System - Network
Manager
16Every 5 minutes (but how much data?)
OMP Server
Collection Specification
Part A every 1 hour Part B every 30
minutes Part C every 5 minutes
OMP
OMP Server (Operations and Maintenance Platform
Server)
17OMP Master Clock
PM Poll for data
PM
PM
PM
18OMP
Web browser
Ethernet
19OMP
Web Server
Web browser
Ethernet
20OMP
Web Server
HTML pages
Web browser
Ethernet
21OMP
Web Server
Generated HTML
HTML pages
CGI Script
Web browser
PM hourly data
Ethernet
22OMP
Web Server
Generated HTML
HTML pages
CGI Script
Web browser
PM hourly data
PM On Demand data
Ethernet
23OMP
Web Server
Generated HTML
HTML pages
CGI Script
On Demand data
Web browser
PM hourly data
PM Hourly Collection
PM On Demand Collection
Ethernet
24OMP
Web Server
Generated HTML
HTML pages
Web Browser
Java applet
CGI Script
PM hourly data
On Demand data
User Terminal
PM Hourly Collection
PM On Demand Collection
Ethernet
25OMP
Web Server
Generated HTML
HTML pages
Web Browser
Java applet Client
CGI Script
PM hourly data
On Demand data
User Terminal
Socket
PM Hourly Collection
PM On Demand Collection Server
Ethernet
26CREATE A SERVER SOCKET AF_INET use TCP/IP
internet protocols SOCK_STREAM connection
oriented socket (not datagrams) s_sock
socket( AF_INET, SOCK_STREAM, 0) Note that this
socket is not yet associated with a port number.
On Demand Collection (server socket)
27CREATE A SERVER SOCKET s_sock socket( AF_INET,
SOCK_STREAM,0) bind will associate s_sock with a
local name or address/port pair. memset(serv_adr,
0, sizeof(serv_adr)) serv_adr.sin_family
AF_INET serv_adr.sin_addr.s_addr
INADDR_ANY serv_adr.sin_port
htons(PORT) bind (s_sock, (struct sockaddr
)(serv_adr), sizeof(serv_adr)) Note that
this port number will be known to all the clients.
On Demand Collection (server socket)
28CREATE A SERVER SOCKET s_sock socket( AF_INET,
SOCK_STREAM,0) bind (s_sock, (struct sockaddr
)(serv_adr), sizeof(serv_adr)) Set up a queue
for incoming connection requests. In this case
set up for a maximum of 5 clients. listen
(s_sock, 5)
On Demand Collection (server socket)
29CREATE A CLIENT SOCKET AF_INET use TCP/IP
internet protocols SOCK_STREAM connection
oriented socket (not datagrams) c_sock
socket( AF_INET, SOCK_STREAM, 0) Note that this
socket is not yet associated with a local or
destination address.
Java applet (socket client)
30CREATE A CLIENT SOCKET c_sock socket( AF_INET,
SOCK_STREAM,0) Connect binds a permanent
destination to a socket, placing it in the
connected state. Internet address interpretation
routine translates from dotted decimal format
(e.g., a.b.c.d) to a 32 bit internet
address. serv_adr.sin_family
AF_INET serv_adr.sin_addr.s_addr
inet_addr(serv_address) serv_adr.sin_port
htons(PORT) connect (c_sock,
(sockaddr )server, sizeof(server))
Java applet (socket client)
31CREATE A CLIENT SOCKET c_sock socket( AF_INET,
SOCK_STREAM,0) connect (c_sock, (sockaddr
)server, sizeof(server)) The client can now
start reading and writing on the socket. Do
buf message to send to the server write
(c_sock, buf, len) read (c_sock, buf,
len) process response message received from
the server while (1) / or until complete /
Java applet (socket client)
32Known port number
On Demand Collection (socket server)
Java applet (socket client)
33CREATE A SERVER SOCKET s_sock socket( AF_INET,
SOCK_STREAM,0) bind (s_sock, (struct sockaddr
)(serv_adr), sizeof(serv_adr)) listen
(s_sock, 5) Once a socket has been set up, the
server needs to wait for a connection. To do so,
it uses system call accept. A call to accept
blocks until a connection request arrives. do
new_sock accept (s_sock, (struct sockaddr
) client_adr, client_len) if (fork()
0) / in CHILD process / while
((lenread(new_sock, buf, size)) / process
message / close (new_sock) exit(0)
else close (new_sock) / in parent / while
(1) / process messages forever /
On Demand Collection (server socket)
34CREATE A SERVER SOCKET s_sock socket( AF_INET,
SOCK_STREAM,0) bind (s_sock, (struct sockaddr
)(serv_adr), sizeof(serv_adr)) listen
(s_sock, 5) new_sock accept (s_sock,
(struct sockaddr ) client_adr,
client_len) When a request arrives, the system
fills in client_adr with the address of the
client that placed the request. The system
creates a new socket file descriptor, new_sock,
that has its destination connected to the
requesting client.
On Demand Collection (server socket)
35Known port Number Listening/ Passive socket
On Demand Collection (socket server)
Java applet (socket client)
Active socket (returned by accept)
When the server accepts a connection from a
client, a new file descriptor is assigned.
36Second Client
Known port number
On Demand Collection (socket server)
Java applet (socket client)
37(No Transcript)
38(No Transcript)
39(No Transcript)
40(No Transcript)
41(No Transcript)
42(No Transcript)
43Question How can we have a single process handle
all the client interfaces and at the same time do
all PM count retrieval from the cells? Why would
we want to do this?
44void ODinit() / Call the signal handler if we
get one a SIGPOLL signal. This indicates
that a socket needs servicing. / (void)
sigset (SIGPOLL, odsig_handler) --- continued
later --- static void ODsig_handler (int
sig) switch (sig) case SIGPOLL sigpoll_
flag TRUE default break
45main ( ) / On Demand collection process
/ ODinit() / initialize the socket
while (1) while (ODwork_to_do()) ODdo_w
ork() ODwait_for_work()
46Void ODwait_for_work ( void ) / Define how
to react to Asynchronous Events - messages
/ uxretval UXWGETMSG ( uxmbuf, UXFOREVER
) switch ( uxretval) case UXMSG /
Process the UXMSG received from a cell - Network
Element / ODuxmsg(uxmbuf ) break case
UXEINTR / Got an interrupt. Handled on
return from this function / break case
UXENOPORT / Somehow the port we are doing
the UXWGETMSG on got
dropped / / Restart the Unix port
/ uxretval UXCONNPORT(ITPT_OD) break
default break
47int ODwork_to_do (void) if (cl1timerflag
cl2timerflag ) return (TRUE) if
(rsp1timerflag rsp2timerflag ) return
(TRUE) if (sigpoll_flag) return
(TRUE) return (FALSE)
48Void ODdo_work ( void ) if (sigpoll_flag) /
Process client request / sigpoll_flag
FALSE ODclient_req() ? remember this
one if (cl1timerflag) / Process periodic
request to Network elements (cells,
..)/ ODmsgdest (ODCL1TIMERTAG) odcl1timerfla
g FALSE if (rsp1timerflag) / Timed out
waiting for response from Network elements
(cells, ..)/ ODerr(ODRSP1TIMERTAG) ODRSP1TIM
ERTAG FALSE if (audit_timer_flag) /
Time for a socket audit / ODsock_audit()
49ODinit continued Void ODinit () /
Initialize the server structure
/ server.sin_addr.s_addr INADDR_ANY server.s
in_family AF_INET / Get the service port
associated with this process usually in
some /etc/ config file such as /etc/services
/ servent_p getservbyname ( PMSERVICE, tcp
) / NOTE API is not IPv6
compliant!/ server.sin_port
servent_p-gts_port / Now create the connection
socket / ODsock socket(AF_INET, SOCK_STREAM,
IPPROTO_TCP) / Allow local address reuse
/ on 1 setsockopt (ODsock, SOL_SOCKET,
SO_REUSEADDR, (char )on, sizeof(on))
50ODinit continued Void ODinit () / Bind
the socket to the local address specified on the
server. This establishes a local address for
the socket. / bind (ODsock, (struct sockaddr
) (server), sizeof(server)) / Set up the
server to listen for connection requests from the
client. This simply marks the socket as
ready to receive a connection. It does not
wait for the client to connect. / (void)
listen (ODsock, 10) / allow 10 connections
pending /
51Question How do we know how many client to allow?
52select() says these file descriptors from the
ODreadmask have work pending
X X X
ODreadmask
Set by FD_SET
X X X X X
FD_ISSET tells if a particular file descriptor
returned by select() has pending work
53ODinit continued Void ODinit () /
Include the socket descriptor in the list of
sockets to poll. Set up the descriptor so
that we get a SIGPOLL when theres something
to read from the socket. / FD_ZERO
(ODreadmask) FD_SET (ODsock, ODreadmask) if
( (rc - ioctl (ODsock, I_SETSIG, S_INPUT ))
-1 ) error / At this point, if we get
any input requests on the connection server
socket, well get a SIGPOLL, call our sigpoll
handler, and set a flag indicating that we
have input on one of our sockets. /
54 Void ODclient_req ( void ) / ODreadmask is a
global file descriptor set. Initially it
includes only the bound (listening) socket
file descriptor. New file descriptors are added
to the ODreadmask after accepting a
connection request. Since select()
modifies the read mask, well have to make a
copy. / memcpy (readfdset, ODreadmask,
sizeof(readfdset)) / select() is used to
determine if there are outstanding requests at
any of the socket fds / numrequests
select (nfds, readfdset, (fd_set )NULL,
(fd_set )NULL, timeout)
55ODclient continued / Loop through all the
client socket file descriptors to determine
the next socket with an outstanding request.
/ for (i 0 i lt nfds i) if (!FD_ISSET
(socknum, readfdset) / nothing for this fd
/ return / If the request is from the
listening socket, do an
accept and add the new socket file
descriptor to the global readmask. otherwise
we have work for a client already connected.
/ if (socknum ODsock) ODconnect_client(
) / New client / else ODapi (socknum)
56Void ODconnect_client ( void ) / accept()
will extract the first connection on the queue
of pending connections, create a new socket
with the properties of ODsock,
and allocate a new file descriptor (clientsock)
for the socket. / clientsock accept (ODsock,
(struct sockaddr )0, i ) / set up this
socket so that it generates a SIGPOLL when it has
input / rc ioctl (clientsock, I_SETSIG,
S_INPUT) / Add the socket to the global read
mask / FD_SET ( clientsock, ODreadmask ) /
We have a valid client. Send a challenge message
to the client. / ODsendchallenge ( clientsock,
challenge_type )
57Void ODsock_audit () / Loop through
connection table - list of all active socket
file desriptors/ / If fd is open, but no
activity for two intervals, close the socket
/ ODclose_sock ( ODconnecti, sockfd ) /
Reset the audit timer / UXTIMER(intvl,
AUDIT_TAG, ODtimer_exp)
58Java applet client side public void run() //
open a socket to the server sock.open(hostName,
portNo) class PModSW public int open(String
hostName, int portNo) sock new
Socket(hostName, portNo) // getInputStream
is the input stream for reading bytes from the
// DataInputStream sockIn new
DataInputStream(sock.getInputStream())
//getOutputStream writes to the
DataOutputstream sockOut new
DataOutputStream (sock.getOutputStream())
59Java applet client side continued public
String getLine() // read response message
from the OMP, // waits until a message is
received line sockIn.readLine() public
int sendReq (byte msg, int offset, int
length) // send a message to the server on
the OMP sockOut.write (msg, offset,
length) // end of PModSW class
60Additional Socket APIs
- - will be discussed in a future lecture
61Socket Options
- Various attributes that are used to determine the
behavior of sockets. - Setting options tells the OS/Protocol Stack the
behavior we want. - Support for generic options (apply to all
sockets) and protocol specific options.
62Setting and Getting option values
- getsockopt() gets the current value of a socket
option. - setsockopt() is used to set the value of a socket
option. - include ltsys/socket.hgt
63getsockopt()
- int getsockopt( int sockfd,
- int level,
- int optname,
- void opval,
- socklen_t optlen)
- level specifies whether the option is a general
option or a protocol specific option (what level
of code should interpret the option).
64setsockopt()
- int setsockopt( int sockfd,
- int level,
- int optname,
- const void opval,
- socklen_t optlen)
65SO_REUSEADDR
- Boolean option enables binding to an address
(port) that is already in use. - Used by servers that are transient - allows
binding a passive socket to a port currently in
use (with active sockets) by other processes. - Can be used to establish separate servers for the
same service on different interfaces (or
different IP addresses on the same interface). - Virtual Web Servers can work this way.
66Signal Driven I/O (R. Stevens, text, chap.22 )
- A signal handler can be installed to instruct the
kernel to generate a SIGIO or SIGPOLL signal
whenever something happens to a socket
descriptor. - The signal handler must determine what conditions
caused the signal and take appropriate action. - See also Stevens, sect. 7.10 fcntl (SVR4) and
ioctl(BSDx) and fcntl (POSIX)
67Signal Driven UDP
- SIGIO occurs whenever
- an incoming datagram arrives.
- an asynchronous error occurs.
- such as unreachable or invalid address
- Could allow process to handle other tasks and
still watch for incoming UDP messages. - Example of signal-driven UDP example described in
the book ( R. Stevens, text, chap.22) - NTP Network Time Protocol.
- Used to record timestamp of arrival of UDP
datagram.
68Signal Driven TCP
- SIGIO occurs whenever
- an incoming connection has completed.
- Disconnect request initiated.
- Disconnect request completed.
- Half a connection shutdown.
- Data has arrived.
- Data has been sent (indicating there is buffer
space) - Asynchronous error