For this assignment, you will be modifying both the card dealer server and the client. You need to imlement a mechanism by which the client can find a card dealer on the network without needing to know its IP address and port. To do this, the client can use UDP broadcast messages to transmit a network-wide request for a server. The card dealer server should monitor a UDP port, and any time it receives a request, it should return a response indicating which TCP port it is using to accept client connections. The client can retrieve the IP address from the response and use that and the port number to connect to the server.
Like some of the other changes you have done, this one really isn't saving much in this circumstance. The server is now free to pick a port number for its TCP socket, but that number will still need to be between 40000 and 40007 to avoid firewall problems. And the server will have to listen on a well-known port for the broadcast requests, so you have just traded having a well-known port for the card dealer service for having a well-known port for the card dealer locator. But it does eliminate the need for you to enter the server's host name or IP address when you run the client.
Now your server will need to open an additional UDP server socket and monitor it for location request messages. You are free to use any of the previous techniques for the card dealer as a starting point; you could use a simple select and just add the UDP socket to the list, spawn a child process just to handle the locator, or use asynchronous I/O. All have their advantages and drawbacks; the select would be pretty straightforward, but if you went with a child process, it would not even need pipes to communicate with the parent; if the child was spawned after the server opened its main TCP server socket, the child could operate independently. It would know the port number for the socket, and it could process requests and return the responses without any interaction with the parent.
On the client side, you will need to open a UDP socket, enable broadcast, and use it to send out a request for a server. Check the information on the setsockopt() call in the Unix Network Programming Manual to see how to enable broadcast. The client should set up the UDP socket, send out a locator request, then wait for responses. Be aware that there could be multiple responses coming back if there is more than one server on the network. The client needs to pick one of those, extract the IP address and port number from the response, and use those to create the TCP connection to the server.
In the event that the client sends a locator request and doesn't receive a response, it should not hang there forever. If it doesn't receive a response within ten seconds, it should send another request. It should repeat this three times, and if after 30 seconds it has received no responses, it should print a message stating that no server could be found an exit. Handling this timeout will require that you modify the client so it doesn't block on the recvfrom() call. You have several techniques available now to do this; you can use a select() with a timeout, set up asynchronous I/O for the socket, or even set the socket to non-blocking mode and poll it. An even simpler, but much lamer, technique would be to set the UDP socket to be non-blocking, send out the locator request, then just sleep for ten seconds and read the socket until it doesn't return any responses. You can pick any of these techniques, but the client must print out a message for each of the locator responses it receives, and it needs to choose one of those with which to actually connect.
In order to make your programs interoperable, implement the UDP locator to meet the following specifications:
Make sure you follow these directions - for the next lab, you will need to run your card dealer client and make sure that it can find and talk to a card dealer server implemented by someone else.
The design should describe the mechanism you will use on the server side to handle the UDP socket along with the other sockets, the mechanism you use on the client side to implement the 10-sec timeouts, and any other decisions you make about the implementation.
You should continue to refine the library of socket functions - for instance, you might add routines that allow you to set a socket for broadcast and to receive messages from a UDP socket with a specified timeout.
You should include the following: