Simple TCP Clients

Close the door behind you!

In this exercise, we want to write a very simple TCP client for the following very simple protocol. In this protocol, the client establishes a connection with the server, then it writes the bytes of a string encoded in UTF-8 and its closes the connexion for writing. Then, the client reads on the connection the bytes of a string encoded in UTF-8 whose end is signaled by the closure of the connexion by the server.

Starting from the file ClientEOS.java, write the method getFixedSizeResponse which takes as argument the string to send, the address of the server and the size of the reception buffer.
If the answer of the server is larger than the size of the reception buffer, we simply ignore the end of the answer.

The main method calls getFixedSizeResponse with:

InetSocketAddress google = new InetSocketAddress("www.google.fr", 80);
getFixedSizeResponse("GET / HTTP/1.1\r\nHost: www.google.fr\r\n\r\n",google,512);
Our client sends the request GET ... to the HTTP server www.google.fr on the its port 80. Once the connection is closed for writing, the server sends the front page for Google.
You should obtain:
HTTP/1.1 200 OK
Date: Tue, 27 Feb 2018 21:35:47 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Set-Cookie: 1P_JAR=2018-02-27-21; expires=Thu, 29-Mar-2018 21:35:47 GMT; path=/; domain=.google.fr
Set-Cookie: NID=124=VPRK8vfhv8XgJdFfzadSN-WSa5C7RvGCOlWBqZ_-Hvnv9O1wWnKSMcXUY3HyNxC2wCoafO7VJ482Bp0njEQV7PtMJeoPjtr_fWH2-

Write the method getUnboundedResponse which reads the full answer from the server, no matter its size.

Our code probably contains several loop aiming at performing reads on the SocketChannel until the work-zone of the ByteBuffer is full.

Write a method boolean readFully(ByteBuffer bb,SocketChannel sc) which fills the ByteBuffer by reading on the SocketChannel. This method returns false if read has returned -1 (before filling the buffer) and true otherwise (buffer is full).

Simplify your code using the method readFully.

All is in the protocol

The previous client has two major drawbacks: it is not very efficient because it manipulates the received data several times to reconstruct the response, and above all it does not allow to reuse the connection for a second request. Thus, we will implement a client that sends and receives information according to a protocol.

The aim of the exercise is to write a client which uses a TCP server to compute the sum of a list of long integers using the following TCP protocol:
  1. the client connects to the server;
  2. the client sends an INT (in big endian) giving the total number of operands to sum followed by each operand (a LONG in big endian);
  3. the client reads the answer from the server which is a LONG (in big endian) corresponding to the sum of the operands;
  4. the server does not close the connection which can be reused by the client to perform another sum by going back to step 2.

Starting from the file ClientLongSum.java, write a client which takes as parameters the address and the port of the server. It will be launched with:

java fr.upem.net.tcp.ClientLongSum localhost 7777
The method requestSumForList(SocketChannel sc, List list) in your client must send the list of operands to the server using the protocol described above and then read the answer from the server and return it.
If the server closes the connection before the end of the exchange, your client will write the following message:
Connection with server lost.
and will terminate.

You should use the method readFully coded in the previous exercice.

You can test your client by starting the server ServerLongSumTCP.jar as follows:

java -jar ServerLongSumTCP.jar 7777

To test the case where the serveur closes the connexion in an unexpected manner, you can start the server with the option -bug which introduces a random probability that the server will close the connection.
java -jar ServerLongSumTCP.jar -bug 7777

Exchanging Strings

The aim of this exercise is to write a client which connects to a server concatenating strings using the following TCP protocol:
  • the client sends a INT (in big endian) giving the number of strings followed by each string encoded as follows: an INT (giving the number of bytes of the string encoded in UTF-8) followed by the bytes representing this string in UTF-8.
  • the server answers with a single string (using the same format) corresponding to the concatenation of all the strings sent by the client joined by semi-colons. More precisely, the servers sends an INT (giving the number of bytes of the string encoded in UTF-8) followed by the bytes representing this string in UTF-8.

You will write a client ClientConcatenation.java which takes as parameter the address and the port of the server. It will be launched using:

java upem.net.tcp.ClientConcatenation localhost 7777
Your client will read strings from the keyboard until it reads an empty string. It will then send these strings (without the empty string) to the server using the protocol and will then print the answer from the server.
If the server closes the connexion before sending the response, your client will write the following message:
Connection with server lost.
and then terminate.

You can test your client by starting the server ServerConcatenationTCP.jar as follows:

java -jar ServerConcatenationTCP.jar 7777
The server will be listening on port 7777.