diff --git a/Reti/Laboratorio/Assigment5/Calculator/client b/Reti/Laboratorio/Assigment5/Calculator/client
new file mode 100755
index 0000000000000000000000000000000000000000..9370d342872f7b132d6304237f6d97e5426ea6a7
Binary files /dev/null and b/Reti/Laboratorio/Assigment5/Calculator/client differ
diff --git a/Reti/Laboratorio/Assigment5/Calculator/client.c b/Reti/Laboratorio/Assigment5/Calculator/client.c
new file mode 100644
index 0000000000000000000000000000000000000000..02a6abfc6cbf1749609115b9c5269187ea4fb8c7
--- /dev/null
+++ b/Reti/Laboratorio/Assigment5/Calculator/client.c
@@ -0,0 +1,134 @@
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[]) {
+  char valueToSend[256] = {'\0'};
+  char valueToReceive[256] = {'\0'};
+  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;
+  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) {
+    printf("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));
+
+  // Avvio il timer
+  gettimeofday(&startTime, NULL);
+
+  // 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) {
+    int num1;
+    int num2;
+    char operator;
+
+    // Pulisco i buffer
+    memset(&valueToReceive, '\0', sizeof(valueToReceive));
+    memset(&valueToSend, '\0', sizeof(valueToSend));
+
+    printf("Inserire il valore da voler inviare al server con il formato num "
+           "num operator: ");
+    scanf("%d %d %c", &num1, &num2, &operator);
+    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/Calculator/makefile b/Reti/Laboratorio/Assigment5/Calculator/makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f0ddf2785d27023f6a46168567b61136c6fc91b9
--- /dev/null
+++ b/Reti/Laboratorio/Assigment5/Calculator/makefile
@@ -0,0 +1,10 @@
+all: client server
+
+client: client.c
+	gcc client.c -o client
+
+server: server.c
+	gcc server.c -o server
+
+clean:
+	rm -f client server
diff --git a/Reti/Laboratorio/Assigment5/Calculator/server b/Reti/Laboratorio/Assigment5/Calculator/server
new file mode 100755
index 0000000000000000000000000000000000000000..ca77de42d76d51f4fb7d79f062bba3f5669284ca
Binary files /dev/null and b/Reti/Laboratorio/Assigment5/Calculator/server differ
diff --git a/Reti/Laboratorio/Assigment5/Calculator/server.c b/Reti/Laboratorio/Assigment5/Calculator/server.c
new file mode 100644
index 0000000000000000000000000000000000000000..01e11ec1e8e9cb092b4c25b0178d1ce46f51ab5e
--- /dev/null
+++ b/Reti/Laboratorio/Assigment5/Calculator/server.c
@@ -0,0 +1,131 @@
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+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);
+  }
+
+  /* lets listen on the socket for connections      */
+  returnStatus = listen(simpleSocket, 5);
+
+  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) {
+    char valueToSend[256] = {'\0'};
+    char valueToRead[256] = {'\0'};
+
+    simpleChildSocket =
+        accept(simpleSocket, (struct sockaddr *)&clientName, &clientNameLength);
+
+    if (simpleChildSocket == -1) {
+      fprintf(stderr, "Cannot accept connections!\n");
+      close(simpleSocket);
+      exit(1);
+    }
+
+    // Leggendo il numero di richieste da svolgere
+    read(simpleChildSocket, valueToRead, sizeof(valueToRead));
+    int iterations = atoi(valueToRead);
+    printf("Numero iterazioni: %d\n", iterations);
+
+    // 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);
+  }
+
+  close(simpleSocket);
+  return 0;
+}