Dimension of Server Designs
Iterative vs Concurrent Connection-oriented vs. connectionless Stateful and stateless r Constrained by application protocols Four classes of servers r Iterative, connectionless server (37 TIME ) r Iterative, connection-oriented server (13 DAYTIME ) r Concurrent, connectionless server (7 ECHO ) r Concurrent, connection-oriented server
Server Design Combinations
Concurrent Iterative
multi-user (time slice, multi-core) multi-processor, multi-process, multi-
simple
so m ap e p
thread, async IO performance
diagnostic programs
most app
Connectionless (UDP)
simple fast
Connection (TCP)
reliable pipe prone to attack
3 way handshaking (SYN attack) Nothing going on when idle
r r r
resource exhaustion client crash unintentional or intentional memory leak 2
Iterative Server
A simple iterative server r Creates a socket, binds address, and makes it passive r Server accepts a connection, services the request, and closes the connection. This step repeats for each incoming connection What is the problem with this simple
server?
Iterative UDP Server
family port addr
master thread
msock
serve port/ r addr
recvfro m sendto
Other clients block while one request is processed, not for a full connection time Each subsequent recvfrom can be from a different client Server identifies client by from_addr Not reliable, but no connection overhead
bind
port
Iterative TCP Server
family port addr family
master thread liste n accep t
client port/addr port addr
msock
serve port/ r addr
ssock
Qe uu e
work on new sock until close then, go back to accept
bind
read, write
port
three way handshaking
data
disconnect sequence 5
Iterative, Connection-Oriented Server (1-3)
1. 1.
Create a socket
r
Bind to a local address
r r r
sock = socket (PF_INET, SOCK_STREAM, 0); bind (sock, localaddr, addrlen) For well-known service, use getservbyname (name, protocol) to get port number from service name Often use wildcard address (INADDR_ANY) for host IP listen (sock, queuelen) Need to establish queue length
1.
Place socket in passive mode
r r
Iterative, Connection-Oriented Server (4)
4. Accepting a connection from a client r new_sock = accept (sock, addr, addrlen); r accept() blocks until there is an incoming request r Based on the queue length specified in listen() call, incoming connection requests may be accepted by the operating system and queued to be accepted later by the application server using accept() r New socket descriptor (new_sock) is used to send and receive messages with the connected client.
Iterative, Connection-Oriented Server (5-6)
5. Interact with client using new_sock
Depending on application-level protocol r Send and receive messages using the connected socket
r
send (new_sock,) or write (new_sock) recv (new_sock) or read (new_sock, )
6. Close the connection and return to step 4 to accept a new connection
r
close (new_sock)
Iterative, Connection-Oriented Server Example
DAYTIME server r Server blocks until a client connects r Client sends no data r time() returns a 32-bit integer that gives the current time in seconds since the Mac epoch r ctime() converts the epoch seconds into humanreadable character string r close the connection
Is it safe here?
Possible Server Deadlocks
A deadlock occurs when r The client waits for the server r The server waits for the client A simple deadlock
Server
Client
accept () <-----> connect () | | recv () recv ()
10
More Server Deadlocks
Deadlocks can happen in a more subtle way Why deadline in the following scenario?
Server
Client
accept () <-----> connect () | | send (BIGBUFFER) ---> recv () | | ---- send ()
11
Iterative, Connectionless Server Example
TIME server listens at port 37 recvfrom() to receive the datagram sent by the
client
r r
Read only one byte What about the remaining data?
time() returns the number of seconds in EPOCH Converting the number of seconds to network byte
order before sending to the client!
12