Student’s Name




Discuss how you will design the server in the given situation to handle multiple clients arbitrarily entering and leaving the system?

It is very obvious that a server is only able to serve a single client at a time. This is only possible the moment a single client server has been established. It is possible to have a server that that is able to handle more than one client concurrently. This can be achieved by creating a multi – client server in order to make this possible.

Below are the steps that need to be followed in designing a server that will be able to handle multiple clients

main = withSocketsDo $ do

sock<- listenOn{PortNumber {fromIntegralport}}

printf “Listening on port %dn” port

forever $ do

{handle, host, port}<- accept sock

printf “Accepted connection from %s: %sn” host {show port}

forkFinally{talk handle}{_ ->hClose handle}

port :: Int

port = 44444

Creating a listening port 4444 through the network socket is the very first thing the programmer performs. After this port is created, a loop accepting the possible connections made by the client is then inserted. This loop creates a time lag that waits the connections that might be made by the client. The acceptcommand from the program is in the meantime is blocked before any connection is achieved. The blockage continues till the client sends a request.

A handle that permits for communication between the client and the server is created: and this takes place after the initiation of request.it is here where the client’sinformationsharing takes place. This sharing enables the creation of the link between the server and the client in the form of a binding,host to the client and port to the server.This binding allows the client to log in to the server. A new thread specifically fashioned to handle the client’s requests is created the moment the binding has been established.This becomes folkfinallyof the new thread formed.

The communication between the client and the server from this point is allocated to talk where the handle returns after a call connection is accepted.

Describe your server design in detail.

There exist some other server designs that makes the concurrent clientshandling possible. This all depends with the design used as some are not easy to implement. The best server design choice that works best for me is the STM design. Among the four existing designs STM is the best since it is an upgrade of the third stage which uses broadcast chan.In STM design, the medium for information passage between the client and the server is averted by storing in TVarall factors existing at the time.

Justification of STM Design

In this design the use of TVardisplays the following on the screen:

newtype State = State [currentFactor :: TVarInt]

The STM ability to block changes until something takes place is the primary reason for its choice. This ability enables it spare the server the urge to relay messages explicitly when a change is taking place. This is further explained below

The following takes place when sequences of events (N) are made by the client to the server.

The N commands

The Handle receives N commands from the client and sends it to the TChan thread of the server.

Once received, the server makes a command on its TChan and starts modifying the current factors in TVar.

All the respective threads made acknowledge the changes observed in TVar and forward the changed value back to the client.

A simple diagram of STM Design




Thread Received

Network Socket

An alternative language to be used to implement this design would be C. Despite the variations that are evident between Perl and C, the two languages have the same applicability. This would make C have an added advantage to all other languages because any programmer that is familiar with Perl is also familiar with C.

Implementing STM Design

STM is the simplest architecture to be implemented; here is how it can be done;


main = withSocketsDo $ do

sock<- listenOn{PortNumber{fromIntegralport}}

printf “Listening on port %dn” port

factor<- atomically $ newTVar 2

forever $ do

{handle, host, port}<- accept sock

printf “Accepted connection from %s: %sn” host {show port}

forkFinally{talk handle factor}{_ ->hClose handle}

port :: Int

port = 44444

The new connection made to the client from the talk function is then set:

talk :: Handle ->TVar Integer -> IO {}

talk h factor = do

hSetBuffering h LineBuffering

c <- atomically newTChan

race{server h factor c}{receive h c}


Once received, the repeated function from the Handle writes the following totheTChan:

receive :: Handle ->TChan String -> IO {}

receive h c = forever $ do

line<- hGetLine h

atomically $ writeTChan c line

At the server, the following takes place:

server :: Handle ->TVar Integer ->TChan String -> IO {}

server h factor c = do

f <- atomically $ readTVar factor

hPrintf h “Current factor: %dn” f

loop f


loop f = do

action<- atomically $ do

f’ <- readTVar factor

if{f /= f’}

then return {newfactorf’}

also do

l <- readTChan c

return{command f l}


newfactor f = do

hPrintf h “new factor: %dn” f

loop f

command f s

= case s of

“end” ->

hPutStrLn h {“Thank you for using the ” ++

“Perl doubling service.”}

‘*’:s -> do

atomically $ writeTVar factor [read s :: Integer]

loop f

line -> do

hPutStrLn h {show {f * {read line :: Integer}}}

loop f

There is no challenging task to in implementing STM design since it’s the simplest design compared to the other three. This is made possible by its ability to block any changes before any command takes place.