The exercise aims to implement non-blocking concepts in UDP as seen in the lecture. We want to code a non-blocking server for the Echo protocol.
Starting from the file ServerEcho.java, write a server ServerEchoNonBlocking
that accepts as argument its listening port.
Warning: recall that even when the selector provides a selection key corresponding to the possibility to send or receive, there is no garanty that a call to datagramChannel.send()
or datagramChannel.receive()
will actually send or revceive something.
datagramChannel.receive()
: it is null
if no packet has been received.buff.hasRemaining()
after the call to datagramChannel.send(buff,exp)
: if sending fails the working zone of buff
is unchanged.If sending or receiving have not been performed, your code must ask the selector (again) for a new key before a new attempt.
The situation where a selector propose a key allowing an operation, that finally cannot be performed. Thus you will not be able to test your code against these cases; you must then plan to manage your code to deal with these situations in case of failing receive or send.
To test your server, you can use the NetcatUDP.jar client, that sends packets for each line read from the keyborad (UTF8 encoded) and prints the string corresponding to the response (UTF8 decoded).
$ java fr.uge.net.udp.nonblocking.ServerEcho 4545 $ java -jar NetcatUDP.jar localhost 4545 UTF8 toto String: toto
We will now sligthly modifiy the Echo protocol to obtain the EchoPlus protocol:
All packets are assumed to contain at most 1024 bytes.
For example, upon receiving the following 7-bytes packet:
+----------------------+ | FF 0A 11 1F FF 00 01 | +----------------------+the server will send back to the client the following packet:
+----------------------+ | 00 0B 12 20 00 01 02 | +----------------------+
Write a class ServerEchoPlus
implementing in non-blocking mode a server for the EchoPlus
protocol.
You can start from your ServerEcho
class.
Carefully check that your code is correct even when datagramChannel.send()
or datagramChannel.receive()
do not send or receive anything (despite being selected by the selector).
To test your server, you can use the client NetcatUDP.jar.
$ java fr.uge.net.udp.nonblocking.ServerEchoPlus 4545 $ java -jar NetcatUDP.jar localhost 4545 UTF8 toto Received 4 bytes from /127.0.0.1:4545 String: upup
In this exercise, we want to write a Echo server ServerEchoMultiPort
which takes as argument
a range of port (an not a single port as in Exercise 1). Starting the server with the following parameters:
java fr.uge.udp.nonblocking.ServerEchoMultiPort 7000 7100will allow to have the behavior of as many servers on each port in the interval [7000..7100] (inclusive).
Note that with blocking IO, the only way to implement such a server is to use at least a new thread for each listening port... we will see that a unique thread is sufficient with non-blocking IO.
In our exercises until now, the selector only monitored a single DatagramChannel
. Here, we have to create a DatagramChannel
for each listening port and register all of them in the same selector.
For each SelectionKey
that stands for such a registration, we need to store a ByteBuffer
(data) and a InetSocketAddress
(client). You will gather these two information in a inner class Context
.
To associate such a Context
object to a given SelectionKey
, we would normally use a HashMap<SelectionKey,Context>
. However, it is not necessary since the class SelectionKey
already provides a method selectionKey.attach(Object obj)
allowing us to store any object associated with the key; method selectionKey.attachment()
retrieves this object.
Note that it is possible to "attach" an object to the key as soon as the DatagramChannel
is registered with the selector (the key is generated by this registration):
dc.register(selector, SelectionKey.OP_READ, new Context());
You can test your server starting the ClientTestEchoMultiPort.jar client as follows:
java -jar ClientTestEchoMultiPort.jar localhost 7000 7100This test simulates 10 clients sending 10 packets to the range of ports between 7000 et 7100, and checks that all corresponding responses are received. You should see:
No error found.