diff --git a/Reti/Laboratorio/Assigment4/EchoServer3/client b/Reti/Laboratorio/Assigment4/EchoServer3/client
index 403f505de9e95754c50e52be97844733e1792cca..79c33a6ff77aeb77a2fd5b3c6b7d48dc45ecb447 100755
Binary files a/Reti/Laboratorio/Assigment4/EchoServer3/client and b/Reti/Laboratorio/Assigment4/EchoServer3/client differ
diff --git a/Reti/Laboratorio/Assigment4/EchoServer3/server b/Reti/Laboratorio/Assigment4/EchoServer3/server
index 4afb8b029004ffe5be2eea8030e5f58cf9ce9552..086f75bdbd06ddcfd9172601c599b9579fc4e5f8 100755
Binary files a/Reti/Laboratorio/Assigment4/EchoServer3/server and b/Reti/Laboratorio/Assigment4/EchoServer3/server differ
diff --git a/Reti/Laboratorio/Assigment5/CharCount/client b/Reti/Laboratorio/Assigment5/CharCount/client
new file mode 100755
index 0000000000000000000000000000000000000000..9370d342872f7b132d6304237f6d97e5426ea6a7
Binary files /dev/null and b/Reti/Laboratorio/Assigment5/CharCount/client differ
diff --git a/Reti/Laboratorio/Assigment5/CharCount/client.c b/Reti/Laboratorio/Assigment5/CharCount/client.c
index 9d8522a0263b9336a736a1fc7ad43f8fe9d12461..22eacc183c0300bdd51a277a6484eb3ad5dbdeaa 100644
--- a/Reti/Laboratorio/Assigment5/CharCount/client.c
+++ b/Reti/Laboratorio/Assigment5/CharCount/client.c
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/socket.h>
+#include <sys/time.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -13,8 +14,15 @@ int main(int argc, char *argv[]) {
   char iterationsServer[256] = {'\0'};
 
   int iterations;
+
+  struct timeval startTime, endTime;
+  double timeServ;
+
   printf("Inserire il numero di iterazioni: ");
   scanf("%d", &iterations);
+  if (!iterations) {
+    exit(1);
+  }
   snprintf(iterationsServer, sizeof(iterationsServer), "%d", iterations);
 
   int simpleSocket = 0;
@@ -55,7 +63,7 @@ int main(int argc, char *argv[]) {
                          sizeof(simpleServer));
 
   if (returnStatus == 0) {
-    fprintf(stderr, "Connect successful!\n");
+    printf("Connect successful!\n");
   } else {
     fprintf(stderr, "Could not connect to address!\n");
     close(simpleSocket);
@@ -63,21 +71,59 @@ int main(int argc, char *argv[]) {
   }
 
   // Inviando il numero di iterazioni al server
-  write(simpleSocket, iterationsServer, strlen(valueToSend));
+  write(simpleSocket, iterationsServer, strlen(iterationsServer));
 
-  for (int i = 0; i < iterations; ++i) {
+  // Avvio il timer
+  gettimeofday(&startTime, NULL);
 
-    /* get the message from the server   */
-    // returnStatus = read(simpleSocket, buffer, sizeof(buffer));
+  // Aspettando l'ACK
+  read(simpleSocket, valueToReceive, sizeof(valueToReceive));
+  if (strcmp(valueToReceive, "ACK") != 0) {
+    fprintf(stderr, "Invalid ACK");
+    exit(0);
+  }
+  printf("%s\n", valueToReceive);
+
+  int i = 0;
+  while (i < iterations) {
+    // Pulisco i buffer
+    memset(&valueToReceive, '\0', sizeof(valueToReceive));
+    memset(&valueToSend, '\0', sizeof(valueToSend));
 
     printf("Inserire il valore da voler inviare al server: ");
     scanf("%s", valueToSend);
-    write(simpleSocket, valueToSend, strlen(valueToSend));
-    read(simpleSocket, valueToReceive, sizeof(valueToReceive));
-    printf("\n\nEcho: %s\n", valueToReceive);
-    close(simpleSocket);
+    if (valueToSend[0] == '\0') {
+      fprintf(stderr, "Impossibile inviare una riga vuota!");
+    } else {
+      write(simpleSocket, valueToSend, strlen(valueToSend));
+      read(simpleSocket, valueToReceive, sizeof(valueToReceive));
+      printf("\n\nEcho: %s\n", valueToReceive);
+      ++i;
+    }
   }
 
+  // Invio il BYE
+  memset(&valueToSend, '\0', sizeof(valueToSend));
+  snprintf(valueToSend, sizeof(valueToSend), "BYE");
+  write(simpleSocket, valueToSend, sizeof(valueToSend));
+
+  // Aspettando l'ACK
+  read(simpleSocket, valueToReceive, sizeof(valueToReceive));
+  if (strcmp(valueToReceive, "ACK") != 0) {
+    fprintf(stderr, "Invalid ACK");
+    exit(0);
+  }
+  printf("%s\n", valueToReceive);
+
   close(simpleSocket);
+
+  // Spengo il timer
+  gettimeofday(&endTime, NULL);
+
+  timeServ = (endTime.tv_sec + (endTime.tv_usec / 1000000.0)) -
+             (startTime.tv_sec + (startTime.tv_usec / 1000000.0));
+
+  printf("Service Time: %.2f", timeServ);
+
   return 0;
 }
diff --git a/Reti/Laboratorio/Assigment5/CharCount/server b/Reti/Laboratorio/Assigment5/CharCount/server
new file mode 100755
index 0000000000000000000000000000000000000000..ca77de42d76d51f4fb7d79f062bba3f5669284ca
Binary files /dev/null and b/Reti/Laboratorio/Assigment5/CharCount/server differ
diff --git a/Reti/Laboratorio/Assigment5/CharCount/server.c b/Reti/Laboratorio/Assigment5/CharCount/server.c
index 6623e4fd0dbb3b7a8949c88a98a1a4c8ecf66034..01e11ec1e8e9cb092b4c25b0178d1ce46f51ab5e 100644
--- a/Reti/Laboratorio/Assigment5/CharCount/server.c
+++ b/Reti/Laboratorio/Assigment5/CharCount/server.c
@@ -74,25 +74,53 @@ int main(int argc, char *argv[]) {
   int clientNameLength = sizeof(clientName);
 
   /* wait here */
+  while (1) {
+    char valueToSend[256] = {'\0'};
+    char valueToRead[256] = {'\0'};
 
-  simpleChildSocket =
-      accept(simpleSocket, (struct sockaddr *)&clientName, &clientNameLength);
+    simpleChildSocket =
+        accept(simpleSocket, (struct sockaddr *)&clientName, &clientNameLength);
 
-  if (simpleChildSocket == -1) {
-    fprintf(stderr, "Cannot accept connections!\n");
-    close(simpleSocket);
-    exit(1);
-  }
+    if (simpleChildSocket == -1) {
+      fprintf(stderr, "Cannot accept connections!\n");
+      close(simpleSocket);
+      exit(1);
+    }
 
-  char bufferRead[256] = {'\0'};
-  read(simpleChildSocket, bufferRead, sizeof(bufferRead));
+    // Leggendo il numero di richieste da svolgere
+    read(simpleChildSocket, valueToRead, sizeof(valueToRead));
+    int iterations = atoi(valueToRead);
+    printf("Numero iterazioni: %d\n", iterations);
 
-  while (1) {
-    // Read message from client
-    read(simpleChildSocket, bufferRead, sizeof(bufferRead));
-    printf("Received: %s\n", bufferRead);
-    char valueToSend[256] = {'\0'};
-    snprintf(valueToSend, sizeof(valueToSend), "%s", bufferRead);
+    // Mando ACK al Client
+    snprintf(valueToSend, sizeof(valueToSend), "ACK");
+    write(simpleChildSocket, valueToSend, sizeof(valueToSend));
+
+    for (int i = 0; i < iterations; ++i) {
+      // Pulisco i buffer
+      memset(valueToRead, '\0', sizeof(valueToRead));
+      memset(valueToSend, '\0', sizeof(valueToSend));
+
+      // Leggo il valore ricevuto dal client e gli restituisco la lunghezza
+      read(simpleChildSocket, valueToRead, sizeof(valueToRead));
+      snprintf(valueToSend, sizeof(valueToSend), "%zu", strlen(valueToRead));
+      write(simpleChildSocket, valueToSend, sizeof(valueToSend));
+    }
+
+    memset(valueToRead, '\0', sizeof(valueToRead));
+    memset(valueToSend, '\0', sizeof(valueToSend));
+
+    // Aspetto il BYE dal client
+    read(simpleChildSocket, valueToRead, sizeof(valueToRead));
+
+    if (strcmp(valueToRead, "BYE") != 0) {
+      fprintf(stderr, "Invalid BYE\n");
+      exit(1);
+    }
+    printf("\tBYE RECEIVED\n");
+
+    // Invio ACK al Server
+    snprintf(valueToSend, sizeof(valueToSend), "ACK");
     write(simpleChildSocket, valueToSend, sizeof(valueToSend));
 
     close(simpleChildSocket);