Fault-tolerance for a sequence of UDP exchanges

Identified packet sent one by one

As in the previous exercise, we want to write a program that turns all the lines of a file in uppercase using a UDP server. In the previous exercise, we saw that this was not possible without changing the protocol.

We now consider the protocol IdUpperCase where each request is prefixed with a id (a long in BigEndian). The id of the request is used to prefix the answer to this request.

Protocol IdUpperCase
A request to the server has the format:
  • a long in BigEndian identifying the request,
  • the bytes of the string encoded in UTF-8.
The answer of the server has the same format using the id of the request. The packets exchanged in this protocol have a maximal size of 1024 bytes.

We provide a server ServerIdUpperCase.jar which implements the protocol IdUpperCase. You can reuse the UDP proxy UDPProxy.jar.

$ java -jar ServerIdUpperCaseUDP.jar 4545 UTF-8
$ java -jar UDPProxy.jar 7777 localhost 4545 -no-swap 

Starting from the template ClientIdUpperCaseUDPOneByOne.java, write a program ClientIdUpperCaseUDPOneByOne to uppercase all the lines of a file using a server.
Your client must send the lines one by one. For instance, if the file contains two lines. The client will first send a request corresponding to the first line with the id 0. If no answer is received with the id 0 before timeout milliseconds, the client will send the request again. This process is repeated until an answer with id 0 is received. Then client moves on the second line using id 1.
As in the previous exercise, the class ClientIdUpperCaseUDPOneByOne.java takes as parameters the two files in-filename and out-filename, the timeout in milliseconds timeout and the address of the server IdUpperCase (hostname port).

Test

You can test your class with the file in.txt using the following line:

$ java fr.uge.net.udp.ClientIdUpperCaseUDPOneByOne in.txt out.txt 300 localhost 7777

Remember to launch the server and UDP proxy as shown above.

Check that your client to not resend the request sooner than timeout millisecondes. This can happen if when you receive an answer with the wrong id, you resend immedialty without checking how much time as ellapsed since the last send.

To help you perform this verification, we provide a fake server ServerIdUpperCaseTestTimeout.jar. This server does not respond to request normally. Every 100 milliseconds, it sends an answer with the id -1. Furthermore it prints the time ellapsed between two receive.

Test your program with the following setup:

$ java -jar ServerIdUpperCaseUDPTestTimeout.jar 7777
$ java fr.uge.net.udp.ClientIdUpperCaseUDPOneByOne in.txt out.txt 300 localhost 7777
If your client respect the timeout, you should see times very close to the timeout timeout.
    Time since last receive: 301 ms
    Time since last receive: 301 ms
    Time since last receive: 301 ms
    Time since last receive: 301 ms
    Time since last receive: 300 ms
    Time since last receive: 301 ms
    ....

Identified packets sent in a burst

The one by one method seen in the previous example is quite slow. Indeed, every time a packet is lost, we have to wait timeout milliseconds before resending it.
A faster approach consists in sending all the requests (with different ids) at the same time. Then during timeout milliseconds, we receive all the answers from the server and store them. After timeout milliseconds, we send again all the request for which we did not receive an answer. And so on, until all the answers have been received.

Starting from the template ClientIdUpperCaseUDPBurst.java, write a client ClientIdUpperCaseUDPBurst.
This class takes the same parameters as the class ClientIdUpperCaseUDPOneByOne.

You can use a java.util.BitSet to keep track of which lines have been received. The main will perform the following tasks:

You have to take into account that the BitSet is accessed concurrently by two threads. You will need a lock to protect the access to the BitSet. The best practice is to design a threadsafe class that contains the BitSet.

You can test your class with the file in.txt as follows:

$ java -jar ServerIdUpperCaseUDP.jar 4545 UTF-8
$ java -jar UDPProxy.jar 7777 localhost 4545 -no-swap 
$ java fr.uge.net.udp.ClientIdUpperCaseUDPBurst in.txt out.txt 300 localhost 7777
    

Do not forget to launch the server and proxy.