/*H******************************************************************************** * Ime datoteke: serverLinux.cpp * * Opis: * Enostaven strežnik, ki zmore sprejeti le enega klienta naenkrat. * Strežnik sprejme klientove podatke in jih v nespremenjeni obliki pošlje * nazaj klientu - odmev. * *H*/ //Vključimo ustrezna zaglavja #include #include #include #include #include #include #include /* Definiramo vrata (port) na katerem bo strežnik poslušal in velikost medponilnika za sprejemanje in pošiljanje podatkov */ #define PORT 10000 #define BUFFER_SIZE 256 #define MAX_CLIENTS 5 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_spinlock_t slock; typedef struct _Client { int clientSock; long connection_start; int sock_ix; } Client; Client clients[MAX_CLIENTS]; int check_if_there_is_space_for_client(Client *socks) { printf("Searching for the first free client\n"); for(int i = 0; i < MAX_CLIENTS; i++) { printf("%d: (%d), ", i, socks[i].sock_ix); if (socks[i].sock_ix == -1) { return i; } } printf("\n"); return -1; } void *handle_client(void *arg) { char buff[BUFFER_SIZE]; Client *c = (Client *)arg; int clientSock = c->clientSock; int sock_ix = c->sock_ix; int iResult; do{ iResult = recv(clientSock, buff, BUFFER_SIZE, 0); if (iResult > 0) { printf("Bytes received: %d\n", iResult); iResult = send(clientSock, buff, iResult, 0 ); if (iResult == -1) { printf("send failed!\n"); close(clientSock); break; } printf("Bytes sent: %d\n", iResult); } else if (iResult == 0) { printf("Closing connection(%d), lasted %ld seconds\n", sock_ix, time(NULL) - c->connection_start); } else{ printf("recv failed!\n"); close(clientSock); break; } } while (iResult > 0); close(clientSock); pthread_spin_lock(&slock); c->sock_ix = -1; pthread_spin_unlock(&slock); pthread_exit(NULL); } int main(int argc, char **argv){ int iResult; int listener= socket(AF_INET, SOCK_STREAM, 0); if (listener == -1) { printf("Error creating clientSock\n"); return 1; } sockaddr_in listenerConf; listenerConf.sin_port=htons(PORT); listenerConf.sin_family=AF_INET; listenerConf.sin_addr.s_addr=INADDR_ANY; iResult = bind( listener, (sockaddr *)&listenerConf, sizeof(listenerConf)); if (iResult == -1) { printf("Bind failed\n"); close(listener); return 1; } if ( listen( listener, 5 ) == -1 ) { printf( "Listen failed\n"); close(listener); return 1; } int clientSock; pthread_spin_init(&slock, PTHREAD_PROCESS_PRIVATE); pthread_t t[MAX_CLIENTS]; Client clients[MAX_CLIENTS]; for(int i = 0; i < MAX_CLIENTS; i++) { clients[i].sock_ix = -1; } while (1) { clientSock = accept(listener,NULL,NULL); if (clientSock == -1) { printf("Accept failed\n"); close(listener); return 1; } pthread_spin_lock(&slock); int sock_ix = check_if_there_is_space_for_client(clients); pthread_spin_unlock(&slock); if (sock_ix < 0) { printf("Too many clients\n"); close(clientSock); } else { clients[sock_ix].sock_ix = sock_ix; clients[sock_ix].clientSock = clientSock; clients[sock_ix].connection_start = time(NULL); printf("Hello i am new client and my idx is %d, my sock descriptor %d\n", sock_ix, clientSock); pthread_create(&t[sock_ix], NULL, handle_client, (void *) &clients[sock_ix]); } } close(listener); pthread_spin_destroy(&slock); return 0; }