#include #include #include #include #include #include #include #include #define PORT 8081 #define BUFFER_SIZE 4096 #define EXPECTED_CONNECTIONS 5 #define TOTAL_TARGET_MB 100 long long global_bytes_received = 0; int connections_handled = 0; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; struct timespec start_time, end_time; int first_connect = 1; void *handle_client(void *socket_desc) { int sock = *(int*)socket_desc; free(socket_desc); char buffer[BUFFER_SIZE]; int valread; long long thread_bytes = 0; while ((valread = read(sock, buffer, BUFFER_SIZE)) > 0) { thread_bytes += valread; } pthread_mutex_lock(&lock); global_bytes_received += thread_bytes; connections_handled++; pthread_mutex_unlock(&lock); close(sock); return NULL; } int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } if (listen(server_fd, 5) < 0) { perror("listen"); exit(EXIT_FAILURE); } printf("TCP Multi-Connection Server listening on port %d...\n", PORT); printf("Waiting for %d connections to transfer total %d MB...\n", EXPECTED_CONNECTIONS, TOTAL_TARGET_MB); pthread_t threads[EXPECTED_CONNECTIONS]; int t_count = 0; while (t_count < EXPECTED_CONNECTIONS) { if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("accept"); exit(EXIT_FAILURE); } if (first_connect) { clock_gettime(CLOCK_MONOTONIC, &start_time); first_connect = 0; printf("First connection received. Timer started.\n"); } int *new_sock = malloc(1); *new_sock = new_socket; if (pthread_create(&threads[t_count], NULL, handle_client, (void*)new_sock) < 0) { perror("could not create thread"); return 1; } t_count++; } // Wait for all threads to finish for (int i = 0; i < EXPECTED_CONNECTIONS; i++) { pthread_join(threads[i], NULL); } clock_gettime(CLOCK_MONOTONIC, &end_time); double time_taken = (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec - start_time.tv_nsec) / 1e9; double mb = global_bytes_received / (1024.0 * 1024.0); double throughput = mb / time_taken; printf("\nTest Finished:\n"); printf("Total Connections: %d\n", connections_handled); printf("Total Data Received: %.2f MB\n", mb); printf("Time Taken: %.2f seconds\n", time_taken); printf("Total Throughput: %.2f MB/s\n", throughput); close(server_fd); return 0; }