164 lines
3.7 KiB
C++
164 lines
3.7 KiB
C++
|
/*H********************************************************************************
|
|||
|
* Ime datoteke: serverLinux.cpp
|
|||
|
*
|
|||
|
* Opis:
|
|||
|
* Enostaven stre<EFBFBD>nik, ki zmore sprejeti le enega klienta naenkrat.
|
|||
|
* Stre<EFBFBD>nik sprejme klientove podatke in jih v nespremenjeni obliki po<EFBFBD>lje
|
|||
|
* nazaj klientu - odmev.
|
|||
|
*
|
|||
|
*H*/
|
|||
|
|
|||
|
//Vklju<6A>imo ustrezna zaglavja
|
|||
|
#include<stdio.h>
|
|||
|
#include<sys/socket.h>
|
|||
|
#include<netinet/in.h>
|
|||
|
#include<unistd.h>
|
|||
|
#include <pthread.h>
|
|||
|
#include <cstdlib>
|
|||
|
#include <ctime>
|
|||
|
|
|||
|
/*
|
|||
|
Definiramo vrata (port) na katerem bo stre<EFBFBD>nik poslu<EFBFBD>al
|
|||
|
in velikost medponilnika za sprejemanje in po<EFBFBD>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;
|
|||
|
}
|