Capulets and Montagues
From Shakespeare's Romeo and Juliet Two rival families always trying to kill each other
Mayhem on Verona's plaza
The answer from the authorities
Prevent Capulets and Montagues to be at the same time
Post guards at two entrances
Overview
Will have to control access to a simulated shared resource (Verona's main plaza)
Will have to writeA client program
Will fork a child for each entity trying to access the shared resource
Will connect to the server to ask permission to enter and to notify it's time to leave
A single-threaded server program
Client side
To make a request to the server, a client will:
1. Create a socket
2. Connect it to the server
3. Send a request to the server
4. Wait for a reply from the server
5. Close the socket
Phone analogy
To connect to the server, a client will:
1. Get a phone
2. Call the server using that number
3. Transmit the request in a single call Montague Aldo wants to enter the plaza Montague Aldo leaves the plaza
4. Wait for a reply
5. Hang up and go away
Server side
Server will:1. Create a socket2. Bind an address to that socket3. Set up a buffer size for that socket4. Wait for incoming calls5. Accept incoming calls (and get a new socket)6. Execute the requested function call7. Repeat steps 4 to 6
Phone analogy
Server will1. Get a phone2. Get a phone number3. Wait for incoming calls4. Accept incoming calls (and transfer them to a new
line)5. Listen to what client says6. Execute the requested function7. Give the answer to the client8. Wait for new incoming calls
High-level view (I)
When the server receives a request from a Montague who want to enter the plaza, it willAllow the request and update the Montague count if no
Capulets are presentDelay its answer otherwise
When the server receives a request from a Capulet who want to enter the plaza, it willAllow the request and update the Capulet count if no
Montagues are presentDelay its answer otherwise
High-level view (II)
When the server is notified that a Montague has left the plaza, it willUpdate the Montague count If the last Montague has left, it will allow in all the
Capulets that were waiting When the server is notified that a Capulet whas left the
plaza, it willUpdate the Capulet count If the last Capulet has left, it will allow it all the
Montagues that were waiting
The server queues
FIFO by default Two queues
Waiting CapuletsWating Montagues
Each entry contains the socket address that was retuned by accept( ) when the server received the request
Only clients that have to wait to enter thr plaza are in the queue
How I would do it
Have a small array in the server
Count Queue
A Capulet roams the plaza looking for Montagues
A Montague is waiting: Its return socket address is 9
1 NIL0 9 NILMontagues
Capulets
TCP socket calls (I) socket(…)
creates a new socket of a given socket type(both client and server sides)
bind(…)binds a socket to a socket address structure (server side)
listen(…)puts a bound TCP socket into listening state (server side)
TCP socket calls (II)
connect(…) requests a new TCP connection from the server (client side)
accept(…)accepts an incoming connect request and creates a new socket associated with the socket address pair of this connection(server side)
Accept "magic" (I)
accept () was designed to implement multithreaded serversEach time it accepts a connect request it
creates a new socket to be used for the duration of that connection
Can, if we want, fork a child to handle that connection
Would be a bad idea this time
TCP socket calls (III) write()
sends data to a remote socket(both client and server sides)
read()receives data from a remote socket(both client and server sides)
close() terminates a TCP connection(both client and server sides)
TCP socket calls (IV)
gethostbyname()returns host address structure associated with a given host name
Your client and your server will both beon the same host and you will do:
gethostname(myname, MAXLEN);hp = get hostbyname(myname);
Summary
Client side:
csd = socket(…)
connect(csd, …)
write(csd, …)
read(csd, …)
close(csd)
Server side:
ssd = socket(…)
bind(…)
listen(…)
newsd = accept(…)
read(newsd, …)
write(newsd, …)
close(newsd)
The connect/accept handshake
For the connect/accept handshake to work,the user stub must specify thehost address (sa.sin_family)port number (sa.sin_port)
of the server in its connect( ) call
Bad news and good news
The bad news is that socket calls are somewhat esotericMight feel you are not fully understanding
what you are writing
The good news is most of these mysterious options are fairly standard
Some examples (I)
// create socket if ((s= socket(AF_INET, SOCK_STREAM, 0)) < 0) return(-1);
With datagram sockets (SOCK_DGRAM), everything would be differentNo listen( ), no accept( ), no connect( )Only sendto( ) and recvfrom( )Message boundaries would be preserved
Some examples (II)
gethostname(myname, MAXHOSTNAME);// get host address structurehp= gethostbyname(myname); sa.sin_family= hp->h_addrtype; // host address sa.sin_port= htons(portnum); // set port number//bind addresss to an existing socketif (bind(s,&sa,sizeof(struct sockaddr_in)) < 0) {
close(s);return(-1);
}
Picking a port number
Your port number should beUnique
Should not interfere with other students' programs
Greater than or equal to 1024 Lower numbers are reserved for privileged
applications
Some examples (III)
// set buffer size for a bound socketlisten(s, 3);
// request a connection// sa must contain address of serverif (connect(s,&sa,sizeof sa) < 0) {
close(s);return(-1);
}