PIR/Serveur.c

269 lines
6.6 KiB
C

/* déclaration des types de base */
#include <sys/types.h>
/* constantes relatives aux domaines, types et protocoles */
#include <sys/socket.h>
/* constantes et structures propres au domaine INTERNET */
#include <netinet/in.h>
/* structures retournées par les fonctions de gestion de la base de
données du réseau */
#include <netdb.h>
/* pour les entrées/sorties */
#include <stdio.h>
/* la lib standard */
#include <stdlib.h>
/* pour le fork */
#include <unistd.h>
/* pour la SHM */
#include <sys/shm.h>
#include <sys/sem.h>
/* pour la manipulation des strings */
#include <string.h>
/* pour le read permissif */
#define SIZE_MAX 32767
// Pour la SHM
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
// L'adresse de la SHM en variable globale pour qu'elle soit accessible depuis les fonctions
int * addr_shm;
// fonctions de manipulation de la SHM
void print_shm() {
printf("La valeur est : %d\n", *addr_shm);
}
void add(int n) {
*addr_shm += n;
}
void sub(int n) {
*addr_shm -= n;
}
void mul(int n) {
*addr_shm *= n;
}
void divi(int n) {
*addr_shm /= n;
}
void reset() {
*addr_shm = 0;
}
int get() {
return *addr_shm;
}
// affichage du nombre de connexions
void print_nb_connexions(int nb_connexions) {
if (nb_connexions == 1) {
printf("Nouvelle connexion, 1ere connexion\n");
} else if (nb_connexions == 2) {
printf("Nouvelle connexion, 2nd connexion\n");
} else {
printf("Nouvelle connexion, %deme connexion\n", nb_connexions);
}
printf("L'adresse du nombre de connexions est : %p\n", &nb_connexions);
}
// Structure pour le traitement des requettes client
struct traitement {
int action;
int arg;
};
// Fonction traitant la phrase reçu et renvoyant une structure traitement
// Fonction qui sera exploitable
struct traitement process(int sock) {
char buff[200];
// PRIMITIVE READ TRES MAL UTILISEE VOLONTAIREMENT
read(sock, buff, SIZE_MAX);
struct traitement ret;
if (!strncmp(buff, "PRINT", 5)) {
ret.action = 1;
} else if (!strncmp(buff, "ADD", 3)) {
ret.action = 2;
read(sock, buff, SIZE_MAX);
ret.arg = atoi(buff);
} else if (!strncmp(buff, "SUB", 3)) {
ret.action = 3;
read(sock, buff, SIZE_MAX);
ret.arg = atoi(buff);
} else if (!strncmp(buff, "MUL", 3)) {
ret.action = 4;
read(sock, buff, SIZE_MAX);
ret.arg = atoi(buff);
} else if (!strncmp(buff, "DIV", 3)) {
ret.action = 5;
read(sock, buff, SIZE_MAX);
ret.arg = atoi(buff);
} else if (!strncmp(buff, "RESET", 5)) {
ret.action = 6;
} else if (!strncmp(buff, "GET", 3)) {
ret.action = 7;
} else {
ret.action = 8;
}
return ret;
}
int main(int argc, char * argv[])
{
if (argc != 2) {
printf("ERREUR : Usage : ./serveur N°Port\n");
exit(2);
}
// Variable pour le test sur le retour des fonctions des librairies
int rt;
// Déclaration des clés
int key_sema = 327;
int key_mem = 328;
// Création de la SHM (dans les deux processus)
int ma_shm;
ma_shm = shmget((key_t)key_mem, sizeof(int), 0666 | IPC_CREAT);
if (ma_shm == -1) {
perror("ERREUR. Echec shmget((key_t)key_mem, sizeof(int), 0666 | IPC_CREAT) \n");
fprintf(stderr, "ERREUR. Echec shmget((key_t)key, sizeof(int), 0666 | IPC_CREAT) \n");
exit(2);
}
addr_shm = (int *)shmat(ma_shm, 0, 0);
if (addr_shm == NULL) {
perror("ERREUR. Echec shmat(ma_shm, 0, 0) \n");
fprintf(stderr, "ERREUR. Echec shmat(ma_shm, 0, 0) \n");
exit(2);
}
// Initialisation de la SHM
*addr_shm = 0;
// Création du semaphore (dans les deux processus)
int sema;
sema = semget((key_t)key_sema, 1, 0666 | IPC_CREAT);
if (sema == -1) {
perror("ERREUR. Echec semget((key_t)key_sema, 1, 0666 | IPC_CREAT) \n");
fprintf(stderr, "ERREUR. Echec semget((key_t)key, 1, 0666 | IPC_CREAT) \n");
exit(2);
}
// Initialisation du sémaphore
union semun arg;
arg.val = 1;
rt = semctl(sema, 0, SETVAL, arg);
if (rt != 0) {
perror("ERREUR. Echec semctl(sema, 0, SETVAL, arg) \n");
fprintf(stderr, "ERREUR. Echec semctl(sema, 0, SETVAL, arg) \n");
exit(2);
}
// La structure pour manipuler les semaphores
struct sembuf buf;
buf.sem_flg = 0;
buf.sem_num = 0;
// On crée le socket local
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
printf("ERREUR lors de la création du socket\n");
exit(1);
}
// On cree l'adresse du socket local
struct sockaddr_in addr_local;
int binder;
addr_local.sin_family = AF_INET;
addr_local.sin_port = atoi(argv[1]);
addr_local.sin_addr.s_addr = INADDR_ANY;
//On bind l'adresse du socket créee avec le socket local
binder = bind(sock,(struct sockaddr *) &addr_local, sizeof(struct sockaddr_in));
if (binder == -1){
printf("ERREUR lors du bind du socket\n");
exit(1);
}
//Initialisation file d'attente
listen(sock, 100);
// Variable de stockage de l'addresse emmeteur
struct sockaddr_in addr_em;
unsigned int longueur_addr_em = sizeof(struct sockaddr_in);
// On se met en état d'acceptation de connexion (et on crée un socket en passant)
int pid = 1;
int nb_connexions = 0;
while (pid != 0){
int sock_connexion = accept(sock, (struct sockaddr *)&addr_em, &longueur_addr_em);
nb_connexions++;
pid = fork();
if (pid == -1){
printf("ERREUR lors du fork\n");
exit(1);
} else if (pid == 0) {
if (sock_connexion == -1) {
printf("ERREUR lors de l'acceptation de la connexion\n");
exit(1);
} else {
// Recupération du traitement
struct traitement taf = process(sock_connexion);
// Prise du Semaphore
buf.sem_op = -1;
rt = semop(sema, &buf, 1);
if (rt != 0) {
perror("ERREUR. EChec semop(sema, &buf, 1) \n");
fprintf(stderr, "ERREUR. Echec semop(sema, &buf, 1) \n");
exit(2);
}
// Traitement
if (taf.action == 1) {
print_shm();
} else if (taf.action == 2) {
add(taf.arg);
} else if (taf.action == 3) {
sub(taf.arg);
} else if (taf.action == 4) {
mul(taf.arg);
} else if (taf.action == 5) {
divi(taf.arg);
} else if (taf.action == 6) {
reset();
} else if (taf.action == 7) {
int val = get();
char val_string[10];
sprintf(val_string, "%d", val);
send(sock_connexion, val_string, strlen(val_string), 0);
}
// Libération du Semaphore
buf.sem_op = 1;
rt = semop(sema, &buf, 1);
if (rt != 0) {
perror("ERREUR. EChec semop(sema, &buf, 1) \n");
fprintf(stderr, "ERREUR. Echec semop(sema, &buf, 1) \n");
exit(2);
}
}
}
}
return 0;
}