Compare commits

..

7 Commits
master ... tcp

Author SHA1 Message Date
MASCARO LUCAS caae36ed9a sa march bitch 2017-02-22 12:35:41 +01:00
MASCARO LUCAS 8558a4f5e4 Merge branch 'tcp' of https://git.xdrm.io/xdrm-brackets/sysdis_tp into tcp 2017-02-22 07:51:45 +01:00
xdrm-brackets d2f1daba07 ended thread management -> freed when finished 2017-02-14 09:56:28 +01:00
xdrm-brackets f641e76a05 Thread implementation ALMOST finished 2017-02-14 09:33:48 +01:00
MASCARO LUCAS 4b8ae83e1f Implémentation du RPC coté serveur 2017-02-14 09:31:49 +01:00
xdrm-brackets fa6265f3d0 TCP socket/branch [FUNC] 2017-02-08 11:44:10 +01:00
xdrm-brackets 2c7431ed69 fuzzy first commit (structure to work on) 2017-02-07 23:17:17 +01:00
17 changed files with 442 additions and 92 deletions

BIN
.server.h.swp Normal file

Binary file not shown.

0
RPC/client.c Normal file
View File

99
RPC/server.c Normal file
View File

@ -0,0 +1,99 @@
#include "server.h"
void traiterClient(int socket){
requete req;
int nb_octet;
int fini=0;
char i = 0;
while(!fini){
nb_octet = read(socket,&req,sizeof(requete));
IF_NB_OCTET_BREAK
if(nb_octet == 0){
break;
}
DEBUG&& printf("Request received (operation/size) : (%d/%d)\n",req.type,req.taille);
switch(req.type){
case FIN:
{
fini = 1;
break;
}
case FACTO:
{
int nb;
long res;
DEBUG&& debug("loop","FACTO asked");
nb_octet = read(socket,&nb,sizeof(int));
IF_NB_OCTET_BREAK
DEBUG&& printf("%d\n",nb);
res = factoriel(nb);
DEBUG&& debug("loop","Sending result");
nb_octet = write(socket, &res, sizeof(res));
IF_NB_OCTET_BREAK
DEBUG&& printf("done\n");
break;
}
case POW:
{
int a,b;
long res;
nb_octet = read(socket, &a, sizeof(int));
IF_NB_OCTET_BREAK
nb_octet = read(socket, &b, sizeof(int));
IF_NB_OCTET_BREAK
res = puissance(a,b);
nb_octet = write(socket, &res, sizeof(res));
IF_NB_OCTET_BREAK
break;
}
case ANALYSE:
{
int nb_elem, attendu;
int* donnees;
char message[MAX_BUFFER_LENGTH];
res_analyse_donnees res;
nb_elem = req.taille/sizeof(int);
donnees = (int*) malloc(nb_elem*sizeof(int));
attendu = req.taille;
while(attendu > 0){
nb_octet = read(socket, message, MAX_BUFFER_LENGTH);
IF_NB_OCTET_BREAK
memcpy(donnees+(req.taille - attendu), message,nb_octet);
attendu -= nb_octet;
}
analyser_donnees(donnees,nb_elem,&res);
write(socket, &res, sizeof(res));
free (donnees);
break;
}
}
}
}

16
RPC/server.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef _RPCSERVER_H_
#define _RPCSERVER_H_
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "../calculs.h"
#include "../lib.h"
#define IF_NB_OCTET_BREAK if(nb_octet == -1){DEBUG&& debug("loop","Breaking the loop\n");fini = 1; break;}
#define MAX_BUFFER_LENGTH 200
void traiterClient(int socket);
#endif

41
calculs.c Normal file
View File

@ -0,0 +1,41 @@
#include "calculs.h"
long factoriel(int nb)
{
int i;
long res;
res = 1;
for (i=nb;i>1;i--)
res = res * i;
return res;
}
void analyser_donnees(int donnees[], int taille, res_analyse_donnees *res)
{
int i;
long somme;
res -> min = donnees[0];
res -> max = donnees[0];
somme = donnees[0];
for (i=1; i < taille; i++)
{
if (donnees[i] > res -> max) res -> max = donnees[i];
if (donnees[i] < res -> min) res -> min = donnees[i];
somme += donnees[i];
}
res -> moy = ((float)somme) / taille;
}
long puissance(int nb, int puiss)
{
long res = nb;
int i;
for (i=1; i < puiss; i++)
res = res * nb;
return res;
}

15
calculs.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _CALCULS_H_
typedef struct {
float moy;
int max;
int min;
}res_analyse_donnees;
long factoriel(int nb);
void analyser_donnees(int donnees[], int taille, res_analyse_donnees *res);
long puissance(int nb, int puiss);
#endif

BIN
client

Binary file not shown.

View File

@ -8,14 +8,16 @@ int main(int argc, char* argv[]){
=========================================================*/ =========================================================*/
/* (1) Socket information */ /* (1) Socket information */
struct sockaddr_in server_addr; // server info struct sockaddr_in server_addr; // server info
int sock; // socket int sock, // socket
int port; // chosen port port; // chosen port
char hostname[24]; // chosen hostname char hostname[24]; // chosen hostname
/* (2) Misc. information */ /* (2) Misc. information */
int bytes; // transfer count int bytes; // transfer count
char* to_send = (char*) malloc( BUFSIZE * sizeof(char) ); char* to_send = (char*) malloc( sizeof(requete)+sizeof(int)+1 );
char* to_recv = (char*) malloc( BUFSIZE * sizeof(char) ); long to_recv;
requete request;
int param;
/* [2] Manage arguments /* [2] Manage arguments
@ -51,36 +53,44 @@ int main(int argc, char* argv[]){
/* [3] Create UPD socket and get target data /* [3] Create TCP socket and get target data
=========================================================*/ =========================================================*/
sock = xconnect(hostname, port, &server_addr); sock = xconnect(hostname, port, &server_addr);
/* (1-) Manage error */ /* (1-) Manage error */
if( sock == -1 ){ if( sock == -1 ){
perror("erreur création socket"); perror("erreur connection server");
exit(1); exit(1);
} }
/* [4] Send message request.type = FACTO;
=========================================================*/ //size of the request isn't important
/* (1) Send message to server */ request.taille = sizeof(int);
bytes = xsend(sock, to_send, &server_addr);
param = 2;
memcpy(to_send,&request,sizeof(requete));
memcpy(to_send+sizeof(requete),&param,sizeof(int));
bytes = write(sock,to_send,sizeof(requete)+sizeof(int));
sleep(2);
param = 3;
memcpy(to_send+sizeof(requete),&param,sizeof(int));
bytes = write(sock,to_send,sizeof(requete)+sizeof(int));
/* (2) Check if send succesfully */
if( bytes == -1 ){ if( bytes == -1 ){
perror("erreur envoi message"); perror("erreur envoi requete");
exit(1); exit(1);
} }
DEBUG&& printf("*** sent %d bytes\n", bytes);
/* [5] Wait for response /* [5] Wait for response
=========================================================*/ =========================================================*/
/* (1) Wait for response */ /* (1) Wait for response */
bytes = xlisten(sock, &server_addr, to_recv, BUFSIZE); bytes = recv(sock, &to_recv, sizeof(long),0);
/* (2) Check if received successfully (and consistently) */ /* (2) Check if received successfully (and consistently) */
if( bytes == -1 ){ if( bytes == -1 ){
@ -89,12 +99,13 @@ int main(int argc, char* argv[]){
} }
/* (4) log */ /* (4) log */
printf("*** received : '%s'\n", to_recv); printf("*** received : '%ld'\n", to_recv);
/* [6] Close socket /* [6] Close socket
=========================================================*/ =========================================================*/
close(sock); close(sock);
printf("Closing socket\n");
return 0; return 0;
} }

BIN
client.o

Binary file not shown.

99
lib.c
View File

@ -25,15 +25,15 @@ int xbind(const int port){
/* [0] Initialization /* [0] Initialization
=========================================================*/ =========================================================*/
int xsocket, bound; int xsocket, bound, clientsock;
static struct sockaddr_in addr; static struct sockaddr_in addr;
/* [1] Create xsocket /* [1] Create xsocket
=========================================================*/ =========================================================*/
/* (1) Create UPD xsocket */ /* (1) Create UPD xsocket */
xsocket = socket(AF_INET, SOCK_DGRAM, 0);
DEBUG&& debug("xbind", "creating server socket"); DEBUG&& debug("xbind", "creating server socket");
xsocket = socket(AF_INET, SOCK_STREAM, 0);
/* (r2-) Manage error */ /* (r2-) Manage error */
if( xsocket == -1 ){ if( xsocket == -1 ){
@ -58,8 +58,8 @@ int xbind(const int port){
/* [3] Bind to port /* [3] Bind to port
=========================================================*/ =========================================================*/
/* (1) Bind and return -1 if error */ /* (1) Bind and return -1 if error */
bound = bind(xsocket, (struct sockaddr*)&addr, sizeof(addr));
DEBUG&& debug("xbind", "binding socket to port"); DEBUG&& debug("xbind", "binding socket to port");
bound = bind(xsocket, (struct sockaddr*)&addr, sizeof(addr));
/* (2) Manage error */ /* (2) Manage error */
if( bound == -1 ){ if( bound == -1 ){
@ -70,7 +70,20 @@ int xbind(const int port){
DEBUG&& printf("done\n"); DEBUG&& printf("done\n");
/* [4] Return xsocket /* [4] Mark socket so it will listen for incoming co.
=========================================================*/
DEBUG&& debug("xbind", "listen for client");
if( listen(xsocket, maxClients) < 0 ){
DEBUG&& printf("error\n");
return -1;
}
DEBUG&& printf("done\n");
/* [5] Return xsocket
=========================================================*/ =========================================================*/
return xsocket; return xsocket;
} }
@ -80,19 +93,52 @@ int xbind(const int port){
int xlisten(const int xsocket, struct sockaddr_in* client){
/* [1] Initialization
=========================================================*/
unsigned int sock_len;
int clientsock;
/* [2] Wait for client
=========================================================*/
/* (1) Wait for incoming client connection */
DEBUG&& debug("xlisten", "listening for client");
clientsock = accept(xsocket, (struct sockaddr*) client, &sock_len);
/* (2) Manage errors */
if( clientsock == -1 ){
DEBUG&& printf("error\n");
return -1;
}
DEBUG&& printf("done\n");
return clientsock;
}
int xconnect(const char* hostname, const int port, struct sockaddr_in* serv){ int xconnect(const char* hostname, const int port, struct sockaddr_in* serv){
/* [0] Initialization /* [0] Initialization
=========================================================*/ =========================================================*/
int xsocket, bound; int xsocket, bound, connected;
struct hostent *host; // data found by lookup struct hostent *host; // data found by lookup
/* [1] Create xsocket /* [1] Create xsocket
=========================================================*/ =========================================================*/
/* (1) Create UPD xsocket */ /* (1) Create UPD xsocket */
xsocket = socket(AF_INET, SOCK_DGRAM, 0);
DEBUG&& debug("xconnect", "creating client socket"); DEBUG&& debug("xconnect", "creating client socket");
xsocket = socket(AF_INET, SOCK_STREAM, 0);
/* (r2-) Manage error */ /* (r2-) Manage error */
if( xsocket == -1 ){ if( xsocket == -1 ){
@ -106,8 +152,8 @@ int xconnect(const char* hostname, const int port, struct sockaddr_in* serv){
/* [2] Get information by hostname /* [2] Get information by hostname
=========================================================*/ =========================================================*/
/* (1) Process */ /* (1) Process */
host = gethostbyname(hostname);
DEBUG&& debug("xconnect", "fetch info by hostname"); DEBUG&& debug("xconnect", "fetch info by hostname");
host = gethostbyname(hostname);
/* (2) Manage error */ /* (2) Manage error */
if( host == NULL ){ if( host == NULL ){
@ -122,8 +168,8 @@ int xconnect(const char* hostname, const int port, struct sockaddr_in* serv){
/* [3] Set server useful information from fetched info /* [3] Set server useful information from fetched info
=========================================================*/ =========================================================*/
/* (1) Reset values */ /* (1) Reset values */
bzero(serv, sizeof(struct sockaddr_in));
DEBUG&& debug("xconnect", "building server info"); DEBUG&& debug("xconnect", "building server info");
bzero(serv, sizeof(struct sockaddr_in));
/* (2) Set server info (ipv4, port) */ /* (2) Set server info (ipv4, port) */
serv->sin_family = AF_INET; serv->sin_family = AF_INET;
@ -135,6 +181,22 @@ int xconnect(const char* hostname, const int port, struct sockaddr_in* serv){
DEBUG&& printf("built\n"); DEBUG&& printf("built\n");
/* [4] Connect to server
=========================================================*/
/* (1) Try to connect to given server */
DEBUG&& debug("xconnect", "connecting to server");
connected = connect(xsocket, (struct sockaddr*) serv, sizeof(*serv));
/* (2) Manage error */
if( connected == -1 ){
DEBUG&& printf("error\n");
return -1;
}
DEBUG&& printf("done\n");
// return socket // return socket
return xsocket; return xsocket;
} }
@ -146,17 +208,16 @@ int xconnect(const char* hostname, const int port, struct sockaddr_in* serv){
int xlisten(const int xsocket, struct sockaddr_in *client, char* buffer, int bufsize){ int xread(const int xsocket, char* buffer, int bufsize){
/* [1] Wait for message through xsocket /* [1] Wait for message through xsocket
=========================================================*/ =========================================================*/
/* (1) Useful data + memory allocation */ /* (1) Memory allocation */
socklen_t sock_len = sizeof(struct sockaddr_in);
buffer = (char*) realloc(buffer, sizeof(char) * bufsize ); buffer = (char*) realloc(buffer, sizeof(char) * bufsize );
/* (2) Listen */ /* (2) Listen */
DEBUG&& debug("xlisten", "waiting for data"); DEBUG&& debug("xread", "waiting for data");
int read = recvfrom(xsocket, buffer, bufsize / sizeof(char) + sizeof(char), 0, (struct sockaddr*) client, &sock_len); int read = recv(xsocket, buffer, bufsize, 0);
/* (3) Manage error */ /* (3) Manage error */
if( read == -1 ){ if( read == -1 ){
@ -166,7 +227,7 @@ int xlisten(const int xsocket, struct sockaddr_in *client, char* buffer, int buf
DEBUG&& printf("received\n"); DEBUG&& printf("received\n");
printf("[xlisten:received] '%s'\n", buffer); DEBUG&& printf("[xread:received] '%s'\n", buffer);
/* [2] Return number of read characters /* [2] Return number of read characters
@ -179,16 +240,16 @@ int xlisten(const int xsocket, struct sockaddr_in *client, char* buffer, int buf
int xsend(const int xsocket, char* buffer, struct sockaddr_in* target){ int xwrite(const int xsocket, char* buffer){
/* [1] Send buffer (message) to target /* [1] Send buffer (message) to target
=========================================================*/ =========================================================*/
/* (1) Useful data */ /* (1) Useful data */
size_t addr_len = sizeof(struct sockaddr_in); unsigned int addr_len = sizeof(struct sockaddr_in);
/* (2) Send data */ /* (2) Send data */
DEBUG&& debug("xsend", "sending data"); DEBUG&& debug("xwrite", "sending data");
int sent = sendto(xsocket, buffer, strlen(buffer)+1, 0, (struct sockaddr*) target, addr_len); int sent = send(xsocket, buffer, strlen(buffer), 0);
/* (3) Manage error */ /* (3) Manage error */
if( sent == -1 ){ if( sent == -1 ){
@ -199,7 +260,7 @@ int xsend(const int xsocket, char* buffer, struct sockaddr_in* target){
DEBUG&& printf("sent\n"); DEBUG&& printf("sent\n");
printf("[xsend:sent] '%s'\n", buffer); DEBUG&& printf("[xwrite:sent] '%s'\n", buffer);
/* [2] Return number of sent characters /* [2] Return number of sent characters

29
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>
@ -31,7 +34,29 @@
int debug(const char* tag, const char* msg); int debug(const char* tag, const char* msg);
int xbind(const int port); int xbind(const int port);
int xlisten(const int xsocket, struct sockaddr_in* client);
int xconnect(const char* hostname, const int port, struct sockaddr_in* serv); int xconnect(const char* hostname, const int port, struct sockaddr_in* serv);
int xlisten(const int xsocket, struct sockaddr_in *client, char* buffer, int bufsize);
int xsend(const int xsocket, char* buffer, struct sockaddr_in* target); int xread(const int xsocket, char* buffer, int bufsize);
int xwrite(const int xsocket, char* buffer);
/************************************************
**** Structs ****
************************************************/
typedef enum
{
FIN=0,
FACTO=1,
POW=2,
ANALYSE=3
}requete_t;
typedef struct {
requete_t type;
int taille;
}requete;
#endif #endif

BIN
lib.o

Binary file not shown.

View File

@ -1,5 +1,7 @@
CC=-Werror -g CC=-Werror -g -pthread
calculs.o: calculs.c calculs.h
gcc $(CC) -c -o calculs.o calculs.c
client.o: client.h client.c client.o: client.h client.c
gcc $(CC) -c -o client.o client.c gcc $(CC) -c -o client.o client.c
@ -10,12 +12,18 @@ server.o: lib.h server.h server.c
lib.o: lib.h lib.c lib.o: lib.h lib.c
gcc $(CC) -c -o lib.o lib.c gcc $(CC) -c -o lib.o lib.c
server: lib.o server.o server: lib.o server.o serverRPC.o calculs.o
gcc $(CC) -o server lib.o server.o gcc $(CC) -o server lib.o server.o serverRPC.o calculs.o
client: lib.o client.o client: lib.o client.o
gcc $(CC) -o client lib.o client.o gcc $(CC) -o client lib.o client.o
clientRPC.o: calculs.h RPC/client.c
gcc $(CC) -c -o clientRPC.o RPC/client.c
serverRPC.o: RPC/server.c RPC/server.h
gcc $(CC) -c -o serverRPC.o RPC/server.c

BIN
server

Binary file not shown.

143
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 sock; 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,64 +35,123 @@ 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
=========================================================*/ =========================================================*/
/* (1) Create socket */ /* (1) Create socket */
sock = xbind(port); listensock = xbind(port);
/* (1-) Manage error */ /* (1-) Manage error */
if( sock == -1 ){ if( listensock == -1 ){
perror("erreur création socket"); perror("erreur création socket");
exit(1); exit(1);
} }
/* [4] Wait for client message /* [4] Wait for clients indefinately
=========================================================*/ =========================================================*/
/* (1) Listen to data */ int i, index = -1; // thread index
bytes = xlisten(sock, &addr_client, to_recv, BUFSIZE); while( 1 ){
/* (1) Listen for incoming connection */
index = -1;
datasock = xlisten(listensock, &addr_client);
DEBUG&& debug("server", "wait for client");
/* (2) Manage error */ /* (2) Manage error */
if( bytes == -1 ){ if( datasock == -1 ){
perror("erreur réception paquet"); DEBUG&& printf("error\n");
exit(1); continue;
} }
// Get client ip DEBUG&& printf("done\n");
inet_ntop(AF_INET, &(addr_client.sin_addr), client_ip, 20);
printf("*** received '%s' (%d bytes) from %s:%d\n", to_recv, bytes, client_ip, ntohs(addr_client.sin_port));
/* [5] Send response /* (3) Search for a free manager */
=========================================================*/ DEBUG&& debug("server", "finding free thread");
/* (1) Send response */ for( i = 0 ; i < maxClients ; i++ )
bytes = xsend(sock, to_send, &addr_client);
/* (2) Manage error */ if( a_managers[i] == 0 ){
if( bytes == -1 ){ DEBUG&& printf("found[%d]\n", i);
perror("erreur envoi réponse"); index = i;
exit(1); break;
} }
/* [6] Close socket /* (4) If we haven't found a free manager -> do nothing (john snow) */
if( index == -1 ){
DEBUG&& printf("not found\n");
continue;
}
/* (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
=========================================================*/ =========================================================*/
close(sock); /* (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; return 0;
} }
void* manageClient(void* pthread_args){
/* [1] Initialization
=========================================================*/
/* (1) Initialize socket data */
struct sockaddr_in addr_client;
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;
DEBUG&& printf("starting the computation loop\n");
//Compute client request
traiterClient(datasock);
/* [2] End process
=========================================================*/
/* (1) Close data socket */
DEBUG&& debug("thread", "closing socket");
close(datasock);
DEBUG&& printf("done\n");
/* (2) Mark manager as inactive again */
DEBUG&& debug("thread", "freeing thread");
a_managers[thread_index] = 0;
DEBUG&& printf("done\n");
}

View File

@ -14,9 +14,26 @@
#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 "RPC/server.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.