diff --git a/Reti/Laboratorio/Assigment4/EchoServer3/client b/Reti/Laboratorio/Assigment4/EchoServer3/client
index 00c3da4cc31d46c2b704caf8973f7f2349388806..403f505de9e95754c50e52be97844733e1792cca 100755
Binary files a/Reti/Laboratorio/Assigment4/EchoServer3/client and b/Reti/Laboratorio/Assigment4/EchoServer3/client differ
diff --git a/Reti/Laboratorio/Assigment4/EchoServer3/client.c b/Reti/Laboratorio/Assigment4/EchoServer3/client.c
index 62c57068e597f4e4e3b0f0c2388f8af043b46bae..b33f594f4f1509d7032d87a3e3453ae824009a29 100644
--- a/Reti/Laboratorio/Assigment4/EchoServer3/client.c
+++ b/Reti/Laboratorio/Assigment4/EchoServer3/client.c
@@ -7,91 +7,92 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-void clean_buffer(void* buffer, size_t buffer_size){ 
-    char* bufferChar = (char *) buffer;
-    for(size_t i = 0; i < buffer_size; ++i){
-        bufferChar[i] = '\0';
-    }
+void clean_buffer(void *buffer, size_t buffer_size) {
+  char *bufferChar = (char *)buffer;
+  for (size_t i = 0; i < buffer_size; ++i) {
+    bufferChar[i] = '\0';
+  }
 }
 
-int main(int argc, char *argv[])
-{
-    char valueToSend[256] = {'\0'};
-    char valueToReceive[256] = {'\0'};
-    char iterationsServer[256] = {'\0'};
-
-    printf("Inserire il numero di iterazioni: ");
-    scanf("%s", iterationsServer);
-
-    int simpleSocket = 0;
-    int simplePort = 0;
-    int returnStatus = 0;
-    char buffer[256] = "";
-    struct sockaddr_in simpleServer;
-
-    if (argc != 3)
-    {
-        fprintf(stderr, "Usage: %s <server> <port>\n", argv[0]);
-        exit(1);
-    }
-
-    /* create a streaming socket      */
-    simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-
-    if (simpleSocket == -1)
-    {
-        fprintf(stderr, "Could not create a socket!\n");
-        exit(1);
-    }
-    else
-    {
-        fprintf(stderr, "Socket created!\n");
-    }
-
-    /* retrieve the port number for connecting */
-    simplePort = atoi(argv[2]);
-
-    /* setup the address structure */
-    /* use the IP address sent as an argument for the server address  */
-    // bzero(&simpleServer, sizeof(simpleServer));
-    memset(&simpleServer, '\0', sizeof(simpleServer));
-    simpleServer.sin_family = AF_INET;
-    // inet_addr(argv[2], &simpleServer.sin_addr.s_addr);
-    simpleServer.sin_addr.s_addr = inet_addr(argv[1]);
-    simpleServer.sin_port = htons(simplePort);
-
-    /*  connect to the address and port with our socket  */
-    returnStatus = connect(simpleSocket, (struct sockaddr *)&simpleServer,
-                           sizeof(simpleServer));
-
-    if (returnStatus == 0)
-    {
-        fprintf(stderr, "Connect successful!\n");
-    }
-    else
-    {
-        fprintf(stderr, "Could not connect to address!\n");
-        close(simpleSocket);
-        exit(1);
-    }
-
-    // Inviando il numero di iterazioni al server
-    write(simpleSocket, iterationsServer, strlen(iterationsServer));
-
-    // Aspettando l'ACK
-    read(simpleSocket, valueToReceive, sizeof(valueToReceive));
-    printf("%s\n", valueToReceive);
-
-    int iterations = atoi(iterationsServer);
-    for (int i = 0; i < iterations; ++i)
-    {
-        clean_buffer((void *) valueToReceive, sizeof(valueToReceive));
-        printf("Inserire il valore da voler inviare al server: ");
-        scanf("%s", valueToSend);
-        write(simpleSocket, valueToSend, strlen(valueToSend));
-        read(simpleSocket, valueToReceive, sizeof(valueToReceive));
-        printf("\nEcho: %s\n", valueToReceive);
-    }
+int main(int argc, char *argv[]) {
+  char valueToSend[256] = {'\0'};
+  char valueToReceive[256] = {'\0'};
+  char iterationsServer[256] = {'\0'};
+
+  printf("Inserire il numero di iterazioni: ");
+  scanf("%s", iterationsServer);
+
+  int simpleSocket = 0;
+  int simplePort = 0;
+  int returnStatus = 0;
+  char buffer[256] = "";
+  struct sockaddr_in simpleServer;
+
+  if (argc != 3) {
+    fprintf(stderr, "Usage: %s <server> <port>\n", argv[0]);
+    exit(1);
+  }
+
+  /* create a streaming socket      */
+  simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+  if (simpleSocket == -1) {
+    fprintf(stderr, "Could not create a socket!\n");
+    exit(1);
+  } else {
+    fprintf(stderr, "Socket created!\n");
+  }
+
+  /* retrieve the port number for connecting */
+  simplePort = atoi(argv[2]);
+
+  /* setup the address structure */
+  /* use the IP address sent as an argument for the server address  */
+  // bzero(&simpleServer, sizeof(simpleServer));
+  memset(&simpleServer, '\0', sizeof(simpleServer));
+  simpleServer.sin_family = AF_INET;
+  // inet_addr(argv[2], &simpleServer.sin_addr.s_addr);
+  simpleServer.sin_addr.s_addr = inet_addr(argv[1]);
+  simpleServer.sin_port = htons(simplePort);
+
+  /*  connect to the address and port with our socket  */
+  returnStatus = connect(simpleSocket, (struct sockaddr *)&simpleServer,
+                         sizeof(simpleServer));
+
+  if (returnStatus == 0) {
+    fprintf(stderr, "Connect successful!\n");
+  } else {
+    fprintf(stderr, "Could not connect to address!\n");
     close(simpleSocket);
-    return 0;
+    exit(1);
+  }
+
+  // Inviando il numero di iterazioni al server
+  write(simpleSocket, iterationsServer, strlen(iterationsServer));
+
+  // Aspettando l'ACK
+  read(simpleSocket, valueToReceive, sizeof(valueToReceive));
+  if (strcmp(valueToReceive, "ACK") != 0) {
+    fprintf(stderr, "Invalid ACK");
+    exit(0);
+  }
+  printf("%s\n", valueToReceive);
+
+  int iterations = atoi(iterationsServer);
+  for (int i = 0; i < iterations; ++i) {
+    clean_buffer((void *)valueToReceive, sizeof(valueToReceive));
+    printf("Inserire il valore da voler inviare al server: ");
+    scanf("%s", valueToSend);
+    write(simpleSocket, valueToSend, strlen(valueToSend));
+    read(simpleSocket, valueToReceive, sizeof(valueToReceive));
+    printf("\nEcho: %s\n", valueToReceive);
+  }
+
+  // Mando BYE
+  clean_buffer((void *)valueToSend, sizeof(valueToSend));
+  snprintf(valueToSend, sizeof(valueToSend), "BYE");
+  write(simpleSocket, valueToSend, sizeof(valueToSend));
+
+  close(simpleSocket);
+  return 0;
 }
diff --git a/Reti/Laboratorio/Assigment4/EchoServer3/server b/Reti/Laboratorio/Assigment4/EchoServer3/server
index c74259722a9539a0f3d04948bf995c13e76a3e20..4afb8b029004ffe5be2eea8030e5f58cf9ce9552 100755
Binary files a/Reti/Laboratorio/Assigment4/EchoServer3/server and b/Reti/Laboratorio/Assigment4/EchoServer3/server differ
diff --git a/Reti/Laboratorio/Assigment4/EchoServer3/server.c b/Reti/Laboratorio/Assigment4/EchoServer3/server.c
index a843b51b1431e1c3fb5a1d8b766cdf2a55f79c66..13eda18bfb0da3648baf5857a67742b50e626a45 100644
--- a/Reti/Laboratorio/Assigment4/EchoServer3/server.c
+++ b/Reti/Laboratorio/Assigment4/EchoServer3/server.c
@@ -9,129 +9,120 @@
 
 // const char MESSAGE[] = "Guess who's back!\n";
 
-void clean_buffer(void* buffer, size_t buffer_size){ 
-    char* bufferChar = (char *) buffer;
-    for(size_t i = 0; i < buffer_size; ++i){
-        bufferChar[i] = '\0';
-    }
+void clean_buffer(void *buffer, size_t buffer_size) {
+  char *bufferChar = (char *)buffer;
+  for (size_t i = 0; i < buffer_size; ++i) {
+    bufferChar[i] = '\0';
+  }
 }
 
-int main(int argc, char *argv[])
-{
-    int simpleSocket = 0;
-    int simplePort = 0;
-    int returnStatus = 0;
-    struct sockaddr_in simpleServer;
-
-    if (argc < 1 || argc > 2)
-    {
-        fprintf(stderr, "Usage: %s <port>\n", argv[0]);
-        exit(1);
+int main(int argc, char *argv[]) {
+  int simpleSocket = 0;
+  int simplePort = 0;
+  int returnStatus = 0;
+  struct sockaddr_in simpleServer;
+
+  if (argc < 1 || argc > 2) {
+    fprintf(stderr, "Usage: %s <port>\n", argv[0]);
+    exit(1);
+  }
+
+  simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+  if (simpleSocket == -1) {
+
+    fprintf(stderr, "Could not create a socket!\n");
+    exit(1);
+  } else {
+    fprintf(stderr, "Socket created!\n");
+  }
+
+  /* retrieve the port number for listening */
+  if (argc == 2) {
+    simplePort = atoi(argv[1]);
+    if (simplePort < 10000 || simplePort > 12000) {
+      fprintf(stderr, "Port must be in range [10000, 12000]\n");
+      exit(1);
     }
+  } else {
+    srand(time(NULL));
+    simplePort = (rand() % 1999) + 10000;
+  }
+
+  /* setup the address structure */
+  /* use INADDR_ANY to bind to all local addresses  */
+  memset(&simpleServer, '\0', sizeof(simpleServer));
+  simpleServer.sin_family = AF_INET;
+  simpleServer.sin_addr.s_addr = htonl(INADDR_ANY);
+  simpleServer.sin_port = htons(simplePort);
+
+  /*  bind to the address and port with our socket */
+  returnStatus = bind(simpleSocket, (struct sockaddr *)&simpleServer,
+                      sizeof(simpleServer));
+
+  if (returnStatus == 0) {
+    fprintf(stderr, "Bind completed on port %d!\n", simplePort);
+  } else {
+    fprintf(stderr, "Could not bind to address!\n");
+    close(simpleSocket);
+    exit(1);
+  }
 
-    simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-
-    if (simpleSocket == -1)
-    {
+  /* lets listen on the socket for connections      */
+  returnStatus = listen(simpleSocket, 5);
 
-        fprintf(stderr, "Could not create a socket!\n");
-        exit(1);
-    }
-    else
-    {
-        fprintf(stderr, "Socket created!\n");
-    }
-
-    /* retrieve the port number for listening */
-    if (argc == 2)
-    {
-        simplePort = atoi(argv[1]);
-        if (simplePort < 10000 || simplePort > 12000)
-        {
-            fprintf(stderr, "Port must be in range [10000, 12000]\n");
-            exit(1);
-        }
-    }
-    else
-    {
-        srand(time(NULL));
-        simplePort = (rand() % 1999) + 10000;
+  if (returnStatus == -1) {
+    fprintf(stderr, "Cannot listen on socket!\n");
+    close(simpleSocket);
+    exit(1);
+  }
+
+  struct sockaddr_in clientName = {0};
+  int simpleChildSocket = 0;
+  int clientNameLength = sizeof(clientName);
+
+  /* wait here */
+  while (1) {
+    simpleChildSocket =
+        accept(simpleSocket, (struct sockaddr *)&clientName, &clientNameLength);
+
+    if (simpleChildSocket == -1) {
+      fprintf(stderr, "Cannot accept connections!\n");
+      close(simpleSocket);
+      exit(1);
     }
 
-    /* setup the address structure */
-    /* use INADDR_ANY to bind to all local addresses  */
-    memset(&simpleServer, '\0', sizeof(simpleServer));
-    simpleServer.sin_family = AF_INET;
-    simpleServer.sin_addr.s_addr = htonl(INADDR_ANY);
-    simpleServer.sin_port = htons(simplePort);
-
-    /*  bind to the address and port with our socket */
-    returnStatus = bind(simpleSocket, (struct sockaddr *)&simpleServer,
-                        sizeof(simpleServer));
-
-    if (returnStatus == 0)
-    {
-        fprintf(stderr, "Bind completed on port %d!\n", simplePort);
-    }
-    else
-    {
-        fprintf(stderr, "Could not bind to address!\n");
-        close(simpleSocket);
-        exit(1);
+    char bufferRead[256] = {'\0'};
+    read(simpleChildSocket, bufferRead, sizeof(bufferRead));
+    printf("Num Iterazioni: %s\n", bufferRead);
+    int iterations = atoi(bufferRead);
+
+    // Send ACK
+    char bufferWrite[256] = {'\0'};
+    snprintf(bufferWrite, sizeof(bufferWrite), "ACK");
+    write(simpleChildSocket, bufferWrite, sizeof(bufferWrite));
+
+    for (int i = 0; i < iterations; ++i) {
+      clean_buffer((void *)bufferRead, sizeof(bufferRead));
+      clean_buffer((void *)bufferWrite, sizeof(bufferWrite));
+
+      char bufferRead[256] = {'\0'};
+      // Read message from client
+      read(simpleChildSocket, bufferRead, sizeof(bufferRead));
+      printf("\tReceived: %s\n", bufferRead);
+      char bufferWrite[256] = {'\0'};
+      snprintf(bufferWrite, sizeof(bufferWrite), "%s", bufferRead);
+      write(simpleChildSocket, bufferWrite, sizeof(bufferWrite));
     }
 
-    /* lets listen on the socket for connections      */
-    returnStatus = listen(simpleSocket, 5);
+    // Wait for BYE
+    clean_buffer((void *)bufferRead, sizeof(bufferRead));
+    read(simpleChildSocket, bufferRead, sizeof(bufferRead));
 
-    if (returnStatus == -1)
-    {
-        fprintf(stderr, "Cannot listen on socket!\n");
-        close(simpleSocket);
-        exit(1);
-    }
+    printf("%s\n", bufferRead);
 
-    struct sockaddr_in clientName = {0};
-    int simpleChildSocket = 0;
-    int clientNameLength = sizeof(clientName);
-
-    /* wait here */
-    while(1){
-        simpleChildSocket =
-            accept(simpleSocket, (struct sockaddr *)&clientName, &clientNameLength);
-
-        if (simpleChildSocket == -1)
-        {
-            fprintf(stderr, "Cannot accept connections!\n");
-            close(simpleSocket);
-            exit(1);
-        }
-
-        char bufferRead[256] = {'\0'};
-        read(simpleChildSocket, bufferRead, sizeof(bufferRead));
-        printf("Num Iterazioni: %s\n", bufferRead);
-        int iterations = atoi(bufferRead);
-
-        //Send ACK
-        char bufferWrite[256] = {'\0'};
-        snprintf(bufferWrite, sizeof(bufferWrite), "ACK");
-        write(simpleChildSocket, bufferWrite, sizeof(bufferWrite));
-
-
-        for (int i = 0; i < iterations; ++i)
-        {
-            clean_buffer((void *) bufferRead, sizeof(bufferRead));
-            clean_buffer((void *) bufferWrite, sizeof(bufferWrite));
-
-            char bufferRead[256] = {'\0'};
-            // Read message from client
-            read(simpleChildSocket, bufferRead, sizeof(bufferRead));
-            printf("\tReceived: %s\n", bufferRead);
-            char bufferWrite[256] = {'\0'};
-            snprintf(bufferWrite, sizeof(bufferWrite), "%s", bufferRead);
-            write(simpleChildSocket, bufferWrite, sizeof(bufferWrite));
-        }
-        close(simpleChildSocket);
-        }
-    close(simpleSocket);
-    return 0;
+    close(simpleChildSocket);
+  }
+  close(simpleSocket);
+  return 0;
 }