Thread implementation ALMOST finished
This commit is contained in:
parent
fa6265f3d0
commit
f641e76a05
Binary file not shown.
Binary file not shown.
2
lib.c
2
lib.c
|
@ -74,7 +74,7 @@ int xbind(const int port){
|
|||
=========================================================*/
|
||||
DEBUG&& debug("xbind", "listen for client");
|
||||
|
||||
if( listen(xsocket, 1) < 0 ){
|
||||
if( listen(xsocket, maxClients) < 0 ){
|
||||
DEBUG&& printf("error\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
3
lib.h
3
lib.h
|
@ -10,6 +10,9 @@
|
|||
#define DEBUG 0x1
|
||||
#define DEBUG_LEN 40
|
||||
|
||||
// constants
|
||||
#define maxClients 0x4
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
2
makefile
2
makefile
|
@ -1,4 +1,4 @@
|
|||
CC=-Werror -g
|
||||
CC=-Werror -g -pthread
|
||||
|
||||
|
||||
client.o: client.h client.c
|
||||
|
|
143
server.c
143
server.c
|
@ -6,19 +6,17 @@ int main(int argc, char* argv[]){
|
|||
|
||||
/* [1] Initialisation
|
||||
=========================================================*/
|
||||
/* (1) Socket info */
|
||||
// Client
|
||||
/* (1) Client address + port */
|
||||
struct sockaddr_in addr_client;
|
||||
char client_ip[20];
|
||||
int port; // chosen port
|
||||
// Socket
|
||||
int port;
|
||||
|
||||
/* (2) Sockets */
|
||||
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
|
||||
|
@ -37,18 +35,6 @@ int main(int argc, char* argv[]){
|
|||
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
|
||||
|
@ -63,20 +49,103 @@ int main(int argc, char* argv[]){
|
|||
}
|
||||
|
||||
|
||||
/* [4] Wait for client
|
||||
/* [4] Wait for clients indefinately
|
||||
=========================================================*/
|
||||
/* (1) Listen to incoming connection */
|
||||
datasock = xlisten(listensock, &addr_client);
|
||||
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);
|
||||
|
||||
/* (2) Manage error */
|
||||
if( datasock == -1 ){
|
||||
DEBUG&& printf("error\n");
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/* (2) Manage error */
|
||||
if( datasock == -1 ){
|
||||
perror("erreur connection client");
|
||||
exit(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;
|
||||
}
|
||||
|
||||
|
||||
/* [5] Wait for data
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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 */
|
||||
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));
|
||||
|
||||
|
||||
/* [6] Send response
|
||||
|
||||
/* [3] Send response
|
||||
=========================================================*/
|
||||
/* (1) Send response */
|
||||
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;
|
||||
|
||||
}
|
||||
|
|
16
server.h
16
server.h
|
@ -14,9 +14,25 @@
|
|||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.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
|
||||
|
|
Loading…
Reference in New Issue