Thread implementation ALMOST finished

This commit is contained in:
xdrm-brackets 2017-02-14 09:33:48 +01:00
parent fa6265f3d0
commit f641e76a05
9 changed files with 130 additions and 38 deletions

BIN
.server.c.swp Normal file

Binary file not shown.

BIN
.server.h.swp Normal file

Binary file not shown.

2
lib.c
View File

@ -74,7 +74,7 @@ int xbind(const int port){
=========================================================*/ =========================================================*/
DEBUG&& debug("xbind", "listen for client"); DEBUG&& debug("xbind", "listen for client");
if( listen(xsocket, 1) < 0 ){ if( listen(xsocket, maxClients) < 0 ){
DEBUG&& printf("error\n"); DEBUG&& printf("error\n");
return -1; return -1;
} }

3
lib.h
View File

@ -10,6 +10,9 @@
#define DEBUG 0x1 #define DEBUG 0x1
#define DEBUG_LEN 40 #define DEBUG_LEN 40
// constants
#define maxClients 0x4
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>

BIN
lib.o

Binary file not shown.

View File

@ -1,4 +1,4 @@
CC=-Werror -g CC=-Werror -g -pthread
client.o: client.h client.c client.o: client.h client.c

137
server.c
View File

@ -6,19 +6,17 @@ int main(int argc, char* argv[]){
/* [1] Initialisation /* [1] Initialisation
=========================================================*/ =========================================================*/
/* (1) Socket info */ /* (1) Client address + port */
// Client
struct sockaddr_in addr_client; struct sockaddr_in addr_client;
char client_ip[20]; int port;
int port; // chosen port
// Socket /* (2) Sockets */
int listensock, datasock; int listensock, datasock;
/* (3) Struct to send arguments to threadable process */
pthread_arg_wrapper built_args = {0, 0};
/* (2) Misc. information */
char* to_send = (char*) malloc( BUFSIZE * sizeof(char) );
char* to_recv = (char*) malloc( BUFSIZE * sizeof(char) );
int bytes; // transfer count
/* [2] Manage arguments /* [2] Manage arguments
@ -37,18 +35,6 @@ int main(int argc, char* argv[]){
return 1; return 1;
} }
/* (3) Manage optional @message argument */
if( argc >= 3 ){
if( strlen(argv[2]) > BUFSIZE || sscanf(argv[2], "%s", to_send) <= 0 ){
printf("argument error: message must be a string (max: %d characters long)\n", BUFSIZE);
return 1;
}
}else
strcpy(to_send, "server default message");
/* [3] Create socket /* [3] Create socket
@ -63,20 +49,103 @@ int main(int argc, char* argv[]){
} }
/* [4] Wait for client /* [4] Wait for clients indefinately
=========================================================*/ =========================================================*/
/* (1) Listen to incoming connection */ int i, index = -1; // thread index
while( 1 ){
/* (1) Listen for incoming connection */
index = -1;
DEBUG&& debug("server", "wait for client");
datasock = xlisten(listensock, &addr_client); datasock = xlisten(listensock, &addr_client);
/* (2) Manage error */ /* (2) Manage error */
if( datasock == -1 ){ if( datasock == -1 ){
perror("erreur connection client"); DEBUG&& printf("error\n");
exit(1); continue;
}
DEBUG&& printf("done\n");
/* (3) Search for a free manager */
DEBUG&& debug("server", "finding free thread");
for( i = 0 ; i < maxClients ; i++ )
if( a_managers[i] == 0 ){
index = i;
break;
} }
/* (4) If we haven't found a free manager -> do nothing (john snow) */
if( index == -1 ){
DEBUG&& printf("not found\n");
continue;
}
/* [5] Wait for data DEBUG&& printf("found\n");
/* (5) Build thread arguments */
built_args.socket = datasock;
built_args.index = index;
/* (6) Processing client connection on a new thread */
pthread_create(&managers[index], NULL, manageClient, (void*)(intptr_t) &built_args);
/* (7) Mark the manager as active */
a_managers[index] = 1;
}
/* [5] Wait for all threads to end
=========================================================*/
/* (1) Wait for all threads to end properly */
for( i = 0 ; i < maxClients ; i++ )
pthread_join(managers[i], NULL);
/* (2) Close listening socket */
close(listensock);
return 0;
}
void* manageClient(void* pthread_args){
/* [1] Initialization
=========================================================*/
/* (1) Initialize socket data */
struct sockaddr_in addr_client;
char* to_send = (char*) malloc( BUFSIZE * sizeof(char) );
char* to_recv = (char*) malloc( BUFSIZE * sizeof(char) );
int bytes; // transfer count
char client_ip[20];
/* (2) Fetch arguments */
pthread_arg_wrapper* arguments = (pthread_arg_wrapper*) (intptr_t) pthread_args;
// get client_socket
int datasock = arguments->socket;
int thread_index = arguments->index;
strcpy(to_send, "server default response");
DEBUG&& debug("thread", "starting thread");
DEBUG&& printf("success[%d]\n", thread_index);
/* [2] Wait for data
=========================================================*/ =========================================================*/
/* (1) wait/read data */ /* (1) wait/read data */
bytes = xread(datasock, to_recv, BUFSIZE); bytes = xread(datasock, to_recv, BUFSIZE);
@ -94,7 +163,8 @@ int main(int argc, char* argv[]){
printf("*** received '%s' (%d bytes) from %s:%d\n", to_recv, bytes, client_ip, ntohs(addr_client.sin_port)); printf("*** received '%s' (%d bytes) from %s:%d\n", to_recv, bytes, client_ip, ntohs(addr_client.sin_port));
/* [6] Send response
/* [3] Send response
=========================================================*/ =========================================================*/
/* (1) Send response */ /* (1) Send response */
bytes = xwrite(datasock, to_send); bytes = xwrite(datasock, to_send);
@ -106,10 +176,13 @@ int main(int argc, char* argv[]){
} }
/* [6] Close socket
=========================================================*/
close(datasock);
close(listensock);
return 0; /* [4] End process
=========================================================*/
/* (1) Close data socket */
close(datasock);
/* (2) Mark manager as inactive again */
managers[thread_index] = 0;
} }

View File

@ -14,9 +14,25 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <errno.h> #include <errno.h>
#include <pthread.h>
#include "lib.h" #include "lib.h"
// DEFINITIONS
typedef struct{
int socket;
int index;
} pthread_arg_wrapper;
// VARIABLES
static pthread_t managers[maxClients]; // containa THREADS
static int a_managers[maxClients] = {0}; // contains THREADS actifs
/************************************************
**** Signatures ****
************************************************/
void* manageClient(void* pthread_args);
#endif #endif

BIN
server.o

Binary file not shown.