Commit 0ae6908740c8484212f66820440c1c7428745d24

Authored by pfrison
1 parent 0042f330

Ajout des fichiers

Debug/Makefile 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +# C'est un exemple, il n'y a pas de source à compiler
  2 +CFLAGS=-I ../libs -lpthread -L ../libs -Wall -Wextra
  3 +
  4 +all:
  5 + gcc *.c -o main.out $(CFLAGS)
  6 +
  7 +debug: CFLAGS += -g -DDEBUG
  8 +debug: all
  9 +
  10 +clean:
  11 + rm -rf *.o *.out
... ...
Debug/Mémo.txt 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +Les balises de débug servent a imprimer des infos suplémentaires en cas de besoin, sans qu'elles apparaissent dans le programme final.
  2 +
  3 +--- Dans le code :
  4 +#ifdef DEBUG
  5 + printf("Je ne print que quand DEBUG est définit\n");
  6 +#endif
  7 +
  8 +--- Dans le make (activation du mode DEBUG)
  9 +debug: CFLAGS += -g -DDEBUG
  10 +debug: all
  11 +
  12 +explication :
  13 + CFLAGS sont les drapeaux passé à gcc (contien des choses comme -lpthread ou autre)
  14 + On y rajoute -g, pour que gcc nous affiche plus d'information sur la compilation
  15 + On y rajoute -DDEBUG, -D permet d'ajouter une balise (comme si on avait fait une #define DEBUG)
  16 + DEBUG est défini donc, les messages se print.
... ...
Librairies/Exemple/Network/Makefile 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +TARGET=libnet
  2 +DIR_TARGET=../libs
  3 +CFLAGS=-Wall -pedantic -Wextra -I $(DIR_TARGET)
  4 +CLIB=ar cq
  5 +CC=gcc
  6 +
  7 +all: $(TARGET).a
  8 +
  9 +debug: CFLAGS += -g -DDEBUG
  10 +debug: all
  11 +
  12 +clean:
  13 + rm -f *.o *.a
  14 + rm -f $(DIR_TARGET)/$(TARGET).a
  15 + rm -f $(DIR_TARGET)/$(TARGET).h
  16 +
  17 +$(TARGET).o: $(TARGET).c $(TARGET).h
  18 + $(CC) -c $(CFLAGS) -o $@ $<
  19 +
  20 +$(TARGET).a: $(TARGET).o
  21 + rm -rf $@
  22 + $(CLIB) $@ $+
  23 + mkdir $(DIR_TARGET) -p
  24 + cp $(TARGET).a $(DIR_TARGET)/$(TARGET).a
  25 + cp $(TARGET).h $(DIR_TARGET)/$(TARGET).h
  26 +
... ...
Librairies/Exemple/Network/libnet.c 0 → 100644
... ... @@ -0,0 +1,277 @@
  1 +#include <sys/types.h>
  2 +#include <sys/socket.h>
  3 +#include <netdb.h>
  4 +#include <errno.h>
  5 +#include <stdlib.h>
  6 +#include <netinet/udp.h>
  7 +#include <netinet/in.h>
  8 +#include <netinet/ip.h>
  9 +#include <string.h>
  10 +#include <stdio.h>
  11 +#include <arpa/inet.h>
  12 +#include <unistd.h>
  13 +#include <stdint.h>
  14 +
  15 +#define MAX_TCP_CONNEXION 10
  16 +#define BUFFER_SIZE 1024
  17 +
  18 +//Fonction permettant d'envoyer en broadcast un message
  19 +void sendUDPBroadcast(unsigned char *message, int taille_message, int port) {
  20 + int broadcast_enable = 1;
  21 + //Option broadcast ON
  22 + int s = socket(AF_INET, SOCK_DGRAM, 0);
  23 + //Création de la socket : s = file descriptor de la socket, AF_INET (socket internet), SOCK_DGRAM (datagramme, UDP, sans connexion)
  24 + if(s < 0){
  25 + //Test de la valeur de retour de la socket
  26 + perror("sendUDPBroadcast.socket");
  27 + exit(-1);
  28 + }
  29 + if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &broadcast_enable, sizeof(broadcast_enable)) < 0) {
  30 + //Mise option broadcast à la socket
  31 + perror("sendUDPBroadcast.setsockopt");
  32 + exit(-1);
  33 + }
  34 +
  35 + struct sockaddr_in broadcast_address;
  36 + memset(&broadcast_address, 0, sizeof(broadcast_address));
  37 + broadcast_address.sin_family = AF_INET;
  38 + broadcast_address.sin_port = htons(port);
  39 + broadcast_address.sin_addr.s_addr = INADDR_BROADCAST; //255.255.255.255
  40 +
  41 + //Envoie du message grâce à la socket
  42 + if(sendto(s, message, taille_message, 0, (struct sockaddr *) &broadcast_address,
  43 + sizeof(broadcast_address)) < 0 ) {
  44 + perror("sendUDPBroadcast.sendto");
  45 + exit(-1);
  46 + }
  47 +}
  48 +
  49 +
  50 +void sendUDPUnicast(char *address, unsigned char *message, int taille_message, int port) {
  51 + int s = socket(AF_INET, SOCK_DGRAM, 0);
  52 + //Création de la socket : s = file descriptor de la socket, AF_INET (socket internet), SOCK_DGRAM (datagramme, UDP, sans connexion)
  53 + if(s < 0){
  54 + //Test de la valeur de retour de la socket
  55 + perror("sendUDPUnicast.socket");
  56 + exit(-1);
  57 + }
  58 + struct sockaddr_in unicast_address;
  59 + //Creation structure adresse de destination
  60 + memset(&unicast_address, 0, sizeof(unicast_address));
  61 + //Mise à zéro de la structure d'adresse
  62 + unicast_address.sin_family = AF_INET;
  63 + unicast_address.sin_port = htons(port);
  64 + //Mise du port en ordre du réseau (big endian)
  65 + unicast_address.sin_addr.s_addr = inet_addr(address);
  66 + if(sendto(s, message, taille_message, 0, (struct sockaddr *) &unicast_address, sizeof(unicast_address)) < 0 ) {
  67 + perror("sendUDPUnicast.sendto");
  68 + exit(-1);
  69 + }
  70 +}
  71 +
  72 +// Retourne l'adresse ip d'une connexion active
  73 +static int socketVersNomUDP(struct sockaddr *padresse, char *nom){
  74 + void *ip;
  75 + int taille_nom;
  76 + if(padresse->sa_family == AF_INET){
  77 + struct sockaddr_in *ipv4 = (struct sockaddr_in *) padresse;
  78 + ip = (void *) &ipv4->sin_addr;
  79 + taille_nom = INET_ADDRSTRLEN;
  80 + }
  81 + if(padresse->sa_family == AF_INET6){
  82 + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) padresse;
  83 + ip = (void *)&ipv6->sin6_addr;
  84 + taille_nom = INET6_ADDRSTRLEN;
  85 + }
  86 + char nom_deco[20];
  87 + inet_ntop(padresse->sa_family, ip, nom_deco, taille_nom);
  88 + sprintf(nom, "%s", nom_deco + 7);
  89 + return 0;
  90 +}
  91 +static int socketVersNomTCP(int s, char *nom){
  92 + struct sockaddr_storage adresse;
  93 + struct sockaddr *padresse = (struct sockaddr *) &adresse;
  94 + socklen_t taille = sizeof adresse;
  95 + int statut;
  96 +
  97 + /* Recupere l'adresse de la socket distante */
  98 + statut = getpeername(s, padresse, &taille);
  99 + if(statut<0){
  100 + perror("socketVersNom.getpeername");
  101 + return -1;
  102 + }
  103 +
  104 + /* Recupere le nom de la machine */
  105 + return socketVersNomUDP(padresse, nom);
  106 +}
  107 +
  108 +// Fonction permettant de créer le serveur TCP
  109 +int initialisationServeurTCP(char *service){
  110 + struct addrinfo precisions, *resultat, *origine;
  111 + int statut;
  112 + int s;
  113 +
  114 + /* Construction de la structure adresse */
  115 + memset(&precisions, 0, sizeof precisions);
  116 + precisions.ai_family = AF_UNSPEC;
  117 + precisions.ai_socktype = SOCK_STREAM;
  118 + precisions.ai_flags = AI_PASSIVE;
  119 + statut = getaddrinfo(NULL, service, &precisions, &origine);
  120 + if(statut < 0){
  121 + perror("initialisationSocketUDP.getaddrinfo");
  122 + exit(EXIT_FAILURE);
  123 + }
  124 + struct addrinfo *p;
  125 + for(p = origine, resultat = origine; p != NULL; p = p->ai_next) {
  126 + if(p->ai_family == AF_INET6){
  127 + resultat = p;
  128 + break;
  129 + }
  130 + }
  131 +
  132 + /* Creation d'une socket */
  133 + s = socket(resultat->ai_family, resultat->ai_socktype, resultat->ai_protocol);
  134 + if(s < 0){
  135 + perror("initialisationSocketUDP.socket");
  136 + exit(EXIT_FAILURE);
  137 + }
  138 +
  139 + /* Options utiles */
  140 + int vrai = 1;
  141 + if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &vrai, sizeof(vrai))<0) {
  142 + perror("initialisationServeurUDPgenerique.setsockopt (REUSEADDR)");
  143 + exit(-1);
  144 + }
  145 +
  146 + /* Specification de l'adresse de la socket */
  147 + statut = bind(s, resultat->ai_addr, resultat->ai_addrlen);
  148 + if(statut<0) {
  149 + perror("initialisationServeurUDP.bind");
  150 + exit(-1);
  151 + }
  152 +
  153 + /* Liberation de la structure d'informations */
  154 + freeaddrinfo(origine);
  155 +
  156 + /* Taille de la queue d'attente */
  157 + statut = listen(s, MAX_TCP_CONNEXION);
  158 + if(statut < 0)
  159 + return -1;
  160 + return s;
  161 +}
  162 +
  163 +// Accepte toutes les connexions au serveur TCP et execute la fonction en argument
  164 +int boucleServeurTCP(int socket, void (*traitement)(int, char *)){
  165 + while(1){
  166 + // accept connection
  167 + struct sockaddr ip_src;
  168 + socklen_t ip_len = sizeof(struct sockaddr);
  169 + int socket_dialogue = accept(socket, &ip_src, &ip_len);
  170 + if(socket_dialogue < 0){
  171 + perror("boucleServeur.accept");
  172 + return -1;
  173 + }
  174 +
  175 + // get ip addr
  176 + char char_ip[20];
  177 + int status = socketVersNomTCP(socket_dialogue, char_ip);
  178 + if(status < 0)
  179 + perror("socketVersNom");
  180 +
  181 + // callback function
  182 + traitement(socket_dialogue, char_ip);
  183 + }
  184 + return 0;
  185 +}
  186 +
  187 +// Creation d'un serveur UDP
  188 +int initialisationServeurUDP(char *service){
  189 + struct addrinfo precisions, *resultat, *origine;
  190 + int statut;
  191 + int s;
  192 +
  193 + /* Construction de la structure adresse */
  194 + memset(&precisions, 0, sizeof precisions);
  195 + precisions.ai_family = AF_UNSPEC;
  196 + precisions.ai_socktype = SOCK_DGRAM;
  197 + precisions.ai_flags = AI_PASSIVE;
  198 + statut = getaddrinfo(NULL, service, &precisions, &origine);
  199 + if(statut < 0){ perror("initialisationSocketUDP.getaddrinfo"); exit(EXIT_FAILURE); }
  200 +
  201 + struct addrinfo *p;
  202 + for(p=origine, resultat=origine; p!=NULL; p=p->ai_next)
  203 + if(p->ai_family == AF_INET6){ resultat=p; break; }
  204 +
  205 + /* Creation d'une socket */
  206 + s = socket(resultat->ai_family, resultat->ai_socktype, resultat->ai_protocol);
  207 + if(s<0){ perror("initialisationSocketUDP.socket"); exit(EXIT_FAILURE); }
  208 +
  209 + /* Options utiles */
  210 + int vrai = 1;
  211 + if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &vrai, sizeof(vrai)) < 0){
  212 + perror("initialisationServeurUDPgenerique.setsockopt (REUSEADDR)");
  213 + exit(-1);
  214 + }
  215 +
  216 + /* Specification de l'adresse de la socket */
  217 + statut = bind(s, resultat->ai_addr, resultat->ai_addrlen);
  218 + if(statut < 0) { perror("initialisationServeurUDP.bind"); exit(-1); }
  219 +
  220 + /* Liberation de la structure d'informations */
  221 + freeaddrinfo(origine);
  222 +
  223 + return s;
  224 +}
  225 +
  226 +// Reception des messages UDP et execute la fonction passee en argument
  227 +int boucleServeurUDP(int s, void (*traitement)(unsigned char *, int, char *)){
  228 + while(1){
  229 + struct sockaddr_storage adresse;
  230 + struct sockaddr *padresse = (struct sockaddr *) &adresse;
  231 + socklen_t taille = sizeof(adresse);
  232 + unsigned char message[BUFFER_SIZE];
  233 +
  234 + int nboctets = recvfrom(s, message, BUFFER_SIZE, 0, (struct sockaddr *) padresse, &taille);
  235 + if(nboctets < 0) return -1;
  236 +
  237 + /* Recupere le nom de la machine */
  238 + char char_ip[20];
  239 + int status = socketVersNomUDP(padresse, char_ip);
  240 + if(status < 0)
  241 + perror("socketVersNom");
  242 +
  243 + traitement(message, nboctets, char_ip);
  244 + }
  245 + return 0;
  246 +}
  247 +
  248 +// Initialise un client TCP
  249 +int openTCPClient(char *hote, int port) {
  250 + int s;
  251 + struct sockaddr_in adresse;
  252 + socklen_t taille = sizeof adresse;
  253 +
  254 + // creation socket
  255 + s = socket(PF_INET, SOCK_STREAM, 0);
  256 + if(s<0){ perror("connexionServeur.socket"); exit(-1); }
  257 +
  258 + // connexion
  259 + memset(&adresse, 0, sizeof(adresse));
  260 + adresse.sin_family=AF_INET;
  261 + adresse.sin_port = htons(port);
  262 + adresse.sin_addr.s_addr = inet_addr(hote);
  263 + if(connect(s,(struct sockaddr *)&adresse, taille)<0) return -1;
  264 + return s;
  265 +}
  266 +
  267 +// Envoie un message TCP sur une connexion active
  268 +void sendTCP(int socket, char *message, int length_message){
  269 + if(length_message <= 0)
  270 + return;
  271 + write(socket, message, length_message);
  272 +}
  273 +
  274 +// Recois un message TCP sur une connexion active
  275 +int receiveTCP(int socket, char *message, int max_length){
  276 + return read(socket, message, max_length);
  277 +}
... ...
Librairies/Exemple/Network/libnet.h 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +#ifndef LIBNET_H
  2 +#define LIBNET_H
  3 +
  4 +#include <stdint.h>
  5 +
  6 +int sendUDPBroadcast(unsigned char *message, int taille_message, int port);
  7 +int sendUDPUnicast(char *address, unsigned char *message, int taille_message, int port);
  8 +
  9 +int initialisationServeurTCP(char *service);
  10 +int boucleServeurTCP(int socket, void (*traitement)(int, char *));
  11 +
  12 +int initialisationServeurUDP(char *service);
  13 +int boucleServeurUDP(int s, void (*traitement)(unsigned char *, int, char *));
  14 +
  15 +int openTCPClient(char *hote, int port);
  16 +void sendTCP(int socket, char *message, int length_message);
  17 +int receiveTCP(int socket, char *message, int max_length);
  18 +
  19 +#endif
... ...
Librairies/Exemple/libs/libnet.a 0 → 100644
No preview for this file type
Librairies/Makefile 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +TARGET=toto
  2 +DIR_TARGET=./toto_lib
  3 +CFLAGS=-Wall -pedantic -Wextra -I $(DIR_TARGET)
  4 +CLIB=ar cq
  5 +CC=gcc
  6 +
  7 +all: $(TARGET).a
  8 +
  9 +debug: CFLAGS += -g -DDEBUG
  10 +debug: all
  11 +
  12 +clean:
  13 + rm -f *.o *.a
  14 + rm -f $(DIR_TARGET)/$(TARGET).a
  15 + rm -f $(DIR_TARGET)/$(TARGET).h
  16 +
  17 +$(TARGET).o: $(TARGET).c $(TARGET).h
  18 + $(CC) -c $(CFLAGS) -o $@ $<
  19 +
  20 +$(TARGET).a: $(TARGET).o
  21 + rm -rf $@
  22 + $(CLIB) $@ $+
  23 + mkdir $(DIR_TARGET) -p
  24 + cp $(TARGET).a $(DIR_TARGET)/$(TARGET).a
  25 + cp $(TARGET).h $(DIR_TARGET)/$(TARGET).h
... ...
Librairies/Mémo.txt 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +Une librairie (un .a) est construit à partir de .o
  2 + Rappel générer un .o : gcc <fichier(s)> -c
  3 +
  4 +Nom d'une librairie : TOUJOURS lib_____.a
  5 +
  6 +Création :
  7 + ar cq <nom_archive> <nom_.o>
  8 +"q" permet la création de la librairie (pour les options taper ar dans le terminal)
  9 +
  10 +Attention : il faut aussi donner le .h avec le .a
  11 +
  12 +Utilisation d'une librairie :
  13 + - #include <_____.h>
  14 + - gcc [...] -L <archives_dir> -I <archives_dir>
  15 +
  16 +Utilisation du squelette Makefile :
  17 + - remplacer "toto" par la cible (ex: libnet)
  18 + - remplacer "./toto_lib" par le dossier qui contiendra la librairie (ex: ../libs)
  19 +
  20 +Ce que fait le make (make all) :
  21 + - compile le TARGET.c en .o
  22 + - crée la librairie .a
  23 + - copie .a et .h dans le dossier DIR_TRAGET
  24 +
  25 +Ce que fait le make clean :
  26 + - efface le .o et le .a dans ./
  27 + - efface le .a et le .h du dossier DIR_TRAGET
  28 +
  29 +Ce que fait le make debug :
  30 + (voir la partie sur les flags de debug dans ../Debug)
0 31 \ No newline at end of file
... ...
Multi_Makefiles/Makefile 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +#
  2 +# Variables d'environnement
  3 +#
  4 +export CC = gcc
  5 +export LD = gcc
  6 +export CLIB = ar cq
  7 +export CFLAGS = -Wall -Wextra -pedantic
  8 +
  9 +#
  10 +# Constantes liees au projet
  11 +#
  12 +
  13 +DIRS = Threads Network Sioux Tangible
  14 +
  15 +#
  16 +# La cible generale
  17 +#
  18 +
  19 +all: $(patsubst %, _dir_%, $(DIRS))
  20 +
  21 +$(patsubst %,_dir_%,$(DIRS)):
  22 + cd $(patsubst _dir_%,%,$@) && make
  23 +
  24 +#
  25 +# La cible de debug
  26 +#
  27 +
  28 +debug: CFLAGS += -g -DDEBUG
  29 +debug: $(patsubst %, _debug_%, $(DIRS))
  30 +
  31 +$(patsubst %,_debug_%,$(DIRS)):
  32 + cd $(patsubst _debug_%,%,$@) && make debug
  33 +
  34 +#
  35 +# La cible de nettoyage
  36 +#
  37 +
  38 +clean: $(patsubst %, _clean_%, $(DIRS))
  39 +
  40 +$(patsubst %,_clean_%,$(DIRS)):
  41 + cd $(patsubst _clean_%,%,$@) && make clean
... ...
Multi_Makefiles/Mémo.txt 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +Appeler un makefile depuis un makefile "maitre".
  2 +
  3 +Dans les makefiles "esclaves", créer les cibles que va appeler le makefile "maitre" (all, clean, debug, etc...)
  4 +
  5 +Pour les appeler à partir du makefile maitre : (ex avec clean)
  6 +
  7 +clean: $(patsubst %, _clean_%, $(DIRS))
  8 +$(patsubst %,_clean_%,$(DIRS)):
  9 + cd $(patsubst _clean_%,%,$@) && make clean
  10 +
  11 +Ce que fait la focntion plus haut :
  12 + - parmis la liste des dossiers donné dans la variable DIRS
  13 + - fait un cd au dossier
  14 + - fait un make clean
  15 +
  16 +Les variables d'environnement (export CC, etc...) ne sont pas obligatoire mais permettent d'unifier les plus communes.
  17 +Exemple : dans le makefile "eclave" $(CC), n'est pas définit mais le makefile "maitre" le définit avec un export CC=gcc.
  18 +
... ...
Signaux/Exemple/Makefile 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +
  2 +all:
  3 + gcc main.c -o main.out
  4 +
  5 +exec: all
  6 + ./main.out
  7 +
  8 +clean:
  9 + rm -rf *.o *.out
0 10 \ No newline at end of file
... ...
Signaux/Exemple/main.c 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +#include <stdio.h>
  2 +#include <stdlib.h> // pour exit(0);
  3 +#include <unistd.h> // pour sleep(1);
  4 +#include <signal.h>
  5 +
  6 +/** Fonction appelé lors de la reception du signal */
  7 +void handler(int sig){
  8 + printf("Signal reçu :%d:", sig);
  9 + exit(0);
  10 +}
  11 +
  12 +int main(void){
  13 + // à mettre en début de main
  14 + struct sigaction action;
  15 + action.sa_handler = handler;
  16 + sigaction(SIGINT, &action, NULL); // On écoute le signal SIGINT (CTRL+C)
  17 +
  18 + // attente / à remplacer par la suite
  19 + while(1) sleep(1);
  20 +}
0 21 \ No newline at end of file
... ...
Signaux/Mémo.txt 0 → 100644
... ... @@ -0,0 +1,78 @@
  1 +#include <signal.h>
  2 +
  3 +--- codes signaux
  4 +Signal CTRL+C = SIGINT (ou 2)
  5 +
  6 +codes complets :
  7 +(voir à la fin / pas très utile)
  8 +
  9 +--- Envoi de signaux :
  10 + int kill(pid_t pid, int sig); // pid_t ~= int
  11 +
  12 +pid : >0 processus précis
  13 + =0 processus dans le même groupe que notre processus
  14 + <0 tous les processus du groupe "-pid"
  15 +
  16 +
  17 +--- Reception de signaux :
  18 +Définition d'un handler (fonction appelé lors de la recpetion d'un signal) :
  19 + void handler(int sig){
  20 + //...
  21 + }
  22 +
  23 +Enregistrement du handler dans sigaction :
  24 + struct sigaction action;
  25 + action.sa_handler;
  26 +
  27 +La fonction sigaction :
  28 + int sigaction(int sig_to_listen, const struct sigaction *sigaction, struct sigaction *sigaction_anc); //sigaction_anc = NULL (très, très) souvent
  29 +
  30 +Déclaration du sigaction pour détecter les signaux (ex: SIG_INT) :
  31 + sigaction(SIGINT, &action, NULL);
  32 +
  33 +--- Attendre un signal
  34 +la fonction :
  35 + int pause (void);
  36 +
  37 +
  38 +--- Commandes terminal utiles
  39 +voir la liste des processus :
  40 + ps / ps -a
  41 +
  42 +tuer un processus avec un signal particulier :
  43 + kill -<signal> <pid> / kill -s <signal> <pid>
  44 + Note : le signal 9 (kill -9 <pid>) tue n'importe quel processus imédiatement
  45 +
  46 +--- Utilisation du squelette
  47 +Remplacer les balises "TODO" par les valeurs souhaitées
  48 +
  49 +
  50 +
  51 +
  52 +--- Tous les codes de signaux
  53 +
  54 +(venant de l'aide de la commande "man 7 signal")
  55 +
  56 +Signal Value Action Comment
  57 +──────────────────────────────────────────────────────────────────────
  58 +SIGHUP 1 Term Hangup detected on controlling terminal
  59 + or death of controlling process
  60 +SIGINT 2 Term Interrupt from keyboard
  61 +SIGQUIT 3 Core Quit from keyboard
  62 +SIGILL 4 Core Illegal Instruction
  63 +SIGABRT 6 Core Abort signal from abort(3)
  64 +SIGFPE 8 Core Floating-point exception
  65 +SIGKILL 9 Term Kill signal
  66 +SIGSEGV 11 Core Invalid memory reference
  67 +SIGPIPE 13 Term Broken pipe: write to pipe with no
  68 + readers; see pipe(7)
  69 +SIGALRM 14 Term Timer signal from alarm(2)
  70 +SIGTERM 15 Term Termination signal
  71 +SIGUSR1 30,10,16 Term User-defined signal 1
  72 +SIGUSR2 31,12,17 Term User-defined signal 2
  73 +SIGCHLD 20,17,18 Ign Child stopped or terminated
  74 +SIGCONT 19,18,25 Cont Continue if stopped
  75 +SIGSTOP 17,19,23 Stop Stop process
  76 +SIGTSTP 18,20,24 Stop Stop typed at terminal
  77 +SIGTTIN 21,21,26 Stop Terminal input for background process
  78 +SIGTTOU 22,22,27 Stop Terminal output for background process
0 79 \ No newline at end of file
... ...
Signaux/Squelette_signaux.c 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +#include <stdio.h>
  2 +#include <signal.h>
  3 +
  4 +void handler(int sig){
  5 + //TODO code à executer à la recpetion du signal...
  6 +}
  7 +
  8 +int main(void){
  9 + struct sigaction action;
  10 + action.sa_handler = handler;
  11 + sigaction(/*TODO signal à écouter...*/, &action, NULL);
  12 +
  13 + // TODO programme normal...
  14 +}
0 15 \ No newline at end of file
... ...
TCP/Client/Makefile 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +
  2 +
  3 +all:
  4 + gcc main.c -o main.out
  5 +
  6 +exec: all
  7 + ./main.out
  8 +
  9 +clean:
  10 + rm -rf *.o *.out
0 11 \ No newline at end of file
... ...
TCP/Client/main.c 0 → 100644
... ... @@ -0,0 +1,74 @@
  1 +#include <stdio.h>
  2 +#include <string.h> // pour strlen()
  3 +#include <stdlib.h> // pour exit()
  4 +#include <sys/socket.h>
  5 +#include <netinet/in.h>
  6 +#include <netinet/ip.h>
  7 +#include <netinet/tcp.h>
  8 +#include <arpa/inet.h>
  9 +#include <unistd.h>
  10 +
  11 +#define BUFFER_SIZE 1000
  12 +
  13 +// Initialise un client TCP, retourne la socket creee
  14 +int openTCPClient(char *hote, int port) {
  15 + int s;
  16 + struct sockaddr_in adresse;
  17 + socklen_t taille = sizeof adresse;
  18 +
  19 + // creation socket
  20 + s = socket(PF_INET, SOCK_STREAM, 0);
  21 + if(s<0){ perror("connexionServeur.socket"); exit(-1); }
  22 +
  23 + // connexion
  24 + memset(&adresse, 0, sizeof(adresse));
  25 + adresse.sin_family=AF_INET;
  26 + adresse.sin_port = htons(port);
  27 + adresse.sin_addr.s_addr = inet_addr(hote);
  28 + if(connect(s,(struct sockaddr *)&adresse, taille)<0) return -1;
  29 + return s;
  30 +}
  31 +
  32 +// Envoie un message TCP sur une connexion active
  33 +void sendTCP(int socket, char *message, int length_message){
  34 + if(length_message <= 0)
  35 + return;
  36 + write(socket, message, length_message);
  37 +}
  38 +
  39 +// Recois un message TCP sur une connexion active. Retourne le nombre de char recu
  40 +int receiveTCP(int socket, char *message, int max_length){
  41 + return read(socket, message, max_length);
  42 +}
  43 +
  44 +// Ferme le connection entre le serveur et le client
  45 +void closeTCPCLient(int socket){
  46 + shutdown(socket, SHUT_RDWR);
  47 +}
  48 +
  49 +int main(void){
  50 + char google_addr[50] = "172.217.7.163";
  51 +
  52 + // Open connection
  53 + int socket = openTCPClient(google_addr, 80);
  54 +
  55 + // Send GET HTTP request test
  56 + char message[1000] = "GET / HTTP/1.1\n\n\0";
  57 + sendTCP(socket, message, strlen(message));
  58 +
  59 + // Recieve HTTP response
  60 + char rep[BUFFER_SIZE];
  61 + int status = receiveTCP(socket, rep, BUFFER_SIZE);
  62 + if(status < 0){
  63 + printf("Erreur de recieve\n");
  64 + exit(-1);
  65 + }
  66 +
  67 + // affichage
  68 + printf("%s\n", rep);
  69 +
  70 + // déconnection
  71 + closeTCPCLient(socket);
  72 +
  73 + return 0;
  74 +}
0 75 \ No newline at end of file
... ...
TCP/Serveur/Makefile 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +
  2 +
  3 +all:
  4 + gcc main.c -o main.out
  5 +
  6 +exec: all
  7 + ./main.out
  8 +
  9 +clean:
  10 + rm -rf *.o *.out
0 11 \ No newline at end of file
... ...
TCP/Serveur/main.c 0 → 100644
... ... @@ -0,0 +1,115 @@
  1 +#include <stdio.h>
  2 +#include <stdlib.h> // pour exit()
  3 +#include <string.h>
  4 +#include <sys/socket.h>
  5 +#include <sys/types.h>
  6 +#include <netinet/in.h>
  7 +#include <netinet/ip.h>
  8 +#include <netinet/tcp.h>
  9 +#include <netdb.h>
  10 +
  11 +#define BUFFER_SIZE 1000
  12 +#define MAX_TCP_CONNEXION 5
  13 +
  14 +// Fonction permettant de créer le serveur TCP
  15 +// service est le numéro ou nom de port (ex: "80" ou "http")
  16 +int initialisationServeurTCP(char *service){
  17 + struct addrinfo precisions, *resultat, *origine;
  18 + int statut;
  19 + int s;
  20 +
  21 + /* Construction de la structure adresse */
  22 + memset(&precisions, 0, sizeof precisions);
  23 + precisions.ai_family = AF_UNSPEC;
  24 + precisions.ai_socktype = SOCK_STREAM;
  25 + precisions.ai_flags = AI_PASSIVE;
  26 + statut = getaddrinfo(NULL, service, &precisions, &origine);
  27 + if(statut < 0){
  28 + perror("initialisationSocketTCP.getaddrinfo");
  29 + exit(EXIT_FAILURE);
  30 + }
  31 + struct addrinfo *p;
  32 + for(p = origine, resultat = origine; p != NULL; p = p->ai_next) {
  33 + if(p->ai_family == AF_INET6){
  34 + resultat = p;
  35 + break;
  36 + }
  37 + }
  38 +
  39 + /* Creation d'une socket */
  40 + s = socket(resultat->ai_family, resultat->ai_socktype, resultat->ai_protocol);
  41 + if(s < 0){
  42 + perror("initialisationSocketTCP.socket");
  43 + exit(EXIT_FAILURE);
  44 + }
  45 +
  46 + /* Options utiles */
  47 + int vrai = 1;
  48 + if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &vrai, sizeof(vrai))<0) {
  49 + perror("initialisationServeurTCPgenerique.setsockopt (REUSEADDR)");
  50 + exit(-1);
  51 + }
  52 +
  53 + /* Specification de l'adresse de la socket */
  54 + statut = bind(s, resultat->ai_addr, resultat->ai_addrlen);
  55 + if(statut<0) {
  56 + perror("initialisationServeurTCP.bind");
  57 + exit(-1);
  58 + }
  59 +
  60 + /* Liberation de la structure d'informations */
  61 + freeaddrinfo(origine);
  62 +
  63 + /* Taille de la queue d'attente */
  64 + statut = listen(s, MAX_TCP_CONNEXION);
  65 + if(statut < 0)
  66 + return -1;
  67 + return s;
  68 +}
  69 +
  70 +// Accepte toutes les connexions au serveur TCP et execute la fonction en argument
  71 +// ATTENTION : non multi-threadé ! -> il faut un pthread_create dans traitement pour le multi-thread.
  72 +int boucleServeurTCP(int socket, void (*traitement)(int)){
  73 + while(1){
  74 + // accept connection
  75 + struct sockaddr ip_src;
  76 + socklen_t ip_len = sizeof(struct sockaddr);
  77 + int socket_dialogue = accept(socket, &ip_src, &ip_len);
  78 + if(socket_dialogue < 0){
  79 + perror("boucleServeur.accept");
  80 + return -1;
  81 + }
  82 +
  83 + // callback function
  84 + traitement(socket_dialogue);
  85 + }
  86 + return 0;
  87 +}
  88 +
  89 +void exemple_traitement(int socket){
  90 + FILE *dialogue = fdopen(socket, "a+");
  91 + if(dialogue==NULL){ perror("gestionClientHTTP.fdopen"); exit(-1); }
  92 +
  93 + char line[BUFFER_SIZE];
  94 + char *success = fgets(line, BUFFER_SIZE, dialogue);
  95 + if(success == NULL){
  96 + fclose(dialogue);
  97 + return;
  98 + }
  99 +
  100 + printf("Message recu :\n\n%s\n", line);
  101 + fprintf(dialogue, "Message recu :\n\n%s\n", line);
  102 +
  103 + fclose(dialogue);
  104 +}
  105 +
  106 +int main(void){
  107 + // init serveur
  108 + char service[50] = "2030";
  109 + int socket = initialisationServeurTCP(service);
  110 +
  111 + // lancement boucle infinie
  112 + boucleServeurTCP(socket, exemple_traitement);
  113 +
  114 + return 0;
  115 +}
0 116 \ No newline at end of file
... ...
Threads/Exemples/Detach/Makefile 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +LIBS=-lpthread
  2 +
  3 +all:
  4 + gcc main.c -o main.out $(LIBS)
  5 +
  6 +exec: all
  7 + ./main.out
  8 +
  9 +clean:
  10 + rm -rf *.out *.o
... ...
Threads/Exemples/Detach/main.c 0 → 100644
... ... @@ -0,0 +1,29 @@
  1 +#include <stdio.h>
  2 +#include <pthread.h>
  3 +
  4 +void *print_hello(void *arg){
  5 + (void) arg; // ici on utilise pas l'argument
  6 + printf("Hello\n");
  7 + pthread_exit(NULL);
  8 +}
  9 +
  10 +void *print_nombre(void *arg){
  11 + int n = *(int *) arg; // void* -> int* -> int
  12 + printf("Le nombre est :%d:\n", n);
  13 + pthread_exit(NULL);
  14 +}
  15 +
  16 +int main(void){
  17 + pthread_t tid1, tid2;
  18 + // thread 1
  19 + pthread_create(&tid1, NULL, print_hello, NULL);
  20 + pthread_detach(tid1);
  21 +
  22 + //thread 2
  23 + int arg = 15;
  24 + pthread_create(&tid2, NULL, print_nombre, (void *) &arg); // int -> int* -> void*
  25 + pthread_detach(tid2);
  26 +
  27 + printf("Je peux terminer le thread principal sans avoir à attendre les deux autre en mode détaché\n");
  28 + pthread_exit(NULL);
  29 +}
0 30 \ No newline at end of file
... ...
Threads/Exemples/Join/Makefile 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +LIBS=-lpthread
  2 +
  3 +all:
  4 + gcc main.c -o main.out $(LIBS)
  5 +
  6 +exec: all
  7 + ./main.out
  8 +
  9 +clean:
  10 + rm -rf *.out *.o
... ...
Threads/Exemples/Join/main.c 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +#include <stdio.h>
  2 +#include <pthread.h>
  3 +
  4 +void *print_hello(void *arg){
  5 + (void) arg; // ici on utilise pas l'argument
  6 + printf("Hello\n");
  7 + pthread_exit(NULL);
  8 +}
  9 +
  10 +void *print_nombre(void *arg){
  11 + int n = *(int *) arg; // void* -> int* -> int
  12 + printf("Le nombre est :%d:\n", n);
  13 + pthread_exit(NULL);
  14 +}
  15 +
  16 +int main(void){
  17 + pthread_t tid1, tid2;
  18 + // thread 1
  19 + pthread_create(&tid1, NULL, print_hello, NULL);
  20 +
  21 + //thread 2
  22 + int arg = 15;
  23 + pthread_create(&tid2, NULL, print_nombre, (void *) &arg); // int -> int* -> void*
  24 +
  25 + // join thread 1
  26 + pthread_join(tid1, NULL);
  27 + printf("Thread 1 terminé\n");
  28 +
  29 + // join thread 2
  30 + pthread_join(tid2, NULL);
  31 + printf("Thread 2 terminé\n");
  32 +
  33 + printf("Je suis obligé de joindre les Threads pour les attendre en mode non-détaché\n");
  34 + pthread_exit(NULL);
  35 +}
0 36 \ No newline at end of file
... ...
Threads/Exemples/Plusieur_args/Makefile 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +LIBS=-lpthread
  2 +
  3 +all:
  4 + gcc main.c -o main.out $(LIBS)
  5 +
  6 +exec: all
  7 + ./main.out
  8 +
  9 +clean:
  10 + rm -rf *.out *.o
... ...
Threads/Exemples/Plusieur_args/main.c 0 → 100644
... ... @@ -0,0 +1,36 @@
  1 +#include <stdio.h>
  2 +#include <pthread.h>
  3 +
  4 +struct deux_int {
  5 + int a;
  6 + int b;
  7 +};
  8 +
  9 +void *print_hello(void *arg){
  10 + (void) arg; // ici on utilise pas l'argument
  11 + printf("Hello\n");
  12 + pthread_exit(NULL);
  13 +}
  14 +
  15 +void *print_nombre(void *arg){
  16 + struct deux_int ints = *(struct deux_int *) arg; // void* -> struct deux_int* -> struct deux_int
  17 + printf("Les nombres sont :%d: et :%d:\n", ints.a, ints.b);
  18 + pthread_exit(NULL);
  19 +}
  20 +
  21 +int main(void){
  22 + pthread_t tid1, tid2;
  23 + // thread 1
  24 + pthread_create(&tid1, NULL, print_hello, NULL);
  25 + pthread_detach(tid1);
  26 +
  27 + //thread 2
  28 + struct deux_int ints;
  29 + ints.a = 15;
  30 + ints.b = 7;
  31 + pthread_create(&tid2, NULL, print_nombre, (void *) &ints); // struct deux_int -> struct deux_int* -> void*
  32 + pthread_detach(tid2);
  33 +
  34 + printf("Je peux terminer le thread principal sans avoir à attendre les deux autre en mode détaché\n");
  35 + pthread_exit(NULL);
  36 +}
0 37 \ No newline at end of file
... ...
Threads/Mémo.txt 0 → 100644
... ... @@ -0,0 +1,114 @@
  1 +Note : à la différence du fork, un thread ne créer pas de nouveau processus.
  2 +
  3 +#include <pthread.h>
  4 +
  5 +--- Compilation /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\
  6 +Avec gcc il faut utiliser -l pthread
  7 + gcc <programme> -l pthread
  8 +
  9 +--- Fonction hôte du thread
  10 +C'est la fonction qui va être executer dans le thread, la forme est toujours :
  11 + void *start_routine(void * args){
  12 + // ...
  13 + }
  14 +
  15 +--- Création du thread
  16 +fonction :
  17 + int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
  18 + thread : id du thread (généré par la fonction)
  19 + attr : attribu, (très, très) souvent NULL
  20 + start_routine : fonction a executer dans le thread
  21 + arg : les argument à passer à start_routine
  22 +
  23 +exemple :
  24 + pthread tid; //thread id
  25 + pthread_create(&tid, NULL, thread_fonction, NULL);
  26 +
  27 +--- Rejoindre un thread
  28 +Suspend le thread qui appel la fonction et attend la terminaison du thread en argument.
  29 +Un tread joinable (c'est le cas par défault) va attendre un pthread_join avant de libérer sa mémoire. Utiliser pthread_detach pour éviter ça.
  30 +
  31 +fonction :
  32 + int pthread_join(pthread_t thread, void **status);
  33 + thread : l'id du thread à attendre
  34 + status : code de retour du thread attendu (généré par la fonction)
  35 +
  36 +exemple :
  37 + pthread_join(tid, NULL);
  38 +
  39 +--- Détachement des threads
  40 +Le mode détaché permet de libérer la mémoire après la terminaison. Sinon, il aurait fallu utiliser pthread_join pour le même résultat.
  41 +
  42 +fonction :
  43 + int pthread_detach(pthread_t thread);
  44 + thread : l'id du tread à détacher
  45 +
  46 +exemple:
  47 + pthread_detach(tid);
  48 +
  49 +--- Terminaison des threads
  50 +Termine le thread qui appel la fonction. Si le thread était le dernier actif, le processus se termine.
  51 +
  52 +fonction :
  53 + void pthread_exit(void *status);
  54 + status : code de terminaison
  55 +
  56 +exemple :
  57 + pthread_exit(NULL);
  58 +
  59 +--- Les arguments des fonctions
  60 +Les arguments sont tous en void*.
  61 +
  62 +Pour faire passer un int (exemple) :
  63 + // -- coté création thread : int -> int* -> void*
  64 + int arg = 5;
  65 + // arg est int
  66 + // &arg est int*
  67 + // (void *) &arg est void*
  68 + pthread_create([...], (void *) &arg);
  69 +
  70 + // coté thread : void* -> int* -> int
  71 + void *arg;
  72 + // arg est void*
  73 + // (int *) arg est int*
  74 + // *((int *) arg) ou *(int *) arg est int
  75 + int n = *(int *) arg;
  76 +
  77 +Pour une chaine de char (exemple) :
  78 + // -- coté création thread : char* -> void*
  79 + char str[50];
  80 + // str est char*
  81 + // (void *) str est void *
  82 + pthread_create([...], (void *) &str);
  83 +
  84 + // coté thread : void* -> char*
  85 + void *arg;
  86 + // arg est void*
  87 + // (char *) arg est char*
  88 + char *str = (char *) arg;
  89 +
  90 +Pour plusieur arguments, utiliser une structure (exemple) :
  91 + struct deux_int {
  92 + int a;
  93 + int b;
  94 + }
  95 +
  96 + // -- coté création thread : struct deux_int -> struct deux_int* -> void*
  97 + int a = 1;
  98 + int b = 3;
  99 + struct deux_int ints;
  100 + ints.a = a;
  101 + ints.b = b;
  102 + // ints est struct deux_int
  103 + // &ints est struct deux_int*
  104 + // (void *) &ints est void*
  105 + pthread_create([...], (void *) &ints);
  106 +
  107 + // coté thread : void* -> struct deux_int* -> struct deux_int
  108 + void *arg;
  109 + // arg est void*
  110 + // (struct deux_int *) arg est struct deux_int*
  111 + // *(struct deux_int *) arg est struct deux_int
  112 + struct deux_int ints = *(struct deux_int *) arg;
  113 + int a = ints.a;
  114 + int b = ints.b;
0 115 \ No newline at end of file
... ...
Threads/Squelette_threads.c 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +#include <stdio.h>
  2 +#include <pthread.h>
  3 +
  4 +void *thread_fonction(void *arg){
  5 +
  6 + // TODO thread code
  7 +
  8 + pthread_exit(NULL);
  9 +}
  10 +
  11 +int main(void){
  12 +
  13 + // TODO initialisation ?
  14 +
  15 + // Création du Thread
  16 + pthread_t tid;
  17 + // TODO thread args ?
  18 + pthread_create(&tid, NULL, thread_fonction, /*args ici ->*/NULL);
  19 + // pthread_detach(tid); ou pthread_join(tid, NULL); ?
  20 + // (il en faut au moins un des deux et un seul des deux)
  21 +
  22 + // TODO suite du programme
  23 +}
0 24 \ No newline at end of file
... ...
UDP/Client/Makefile 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +
  2 +
  3 +all:
  4 + gcc main.c -o main.out
  5 +
  6 +exec: all
  7 + ./main.out
  8 +
  9 +clean:
  10 + rm -rf *.o *.out
0 11 \ No newline at end of file
... ...
UDP/Client/main.c 0 → 100644
... ... @@ -0,0 +1,76 @@
  1 +#include <stdio.h>
  2 +#include <string.h> // pour strlen()
  3 +#include <stdlib.h> // pour exit()
  4 +#include <sys/socket.h>
  5 +#include <netinet/in.h>
  6 +#include <netinet/ip.h>
  7 +#include <netinet/udp.h>
  8 +#include <arpa/inet.h>
  9 +
  10 +//Fonction permettant d'envoyer un message en broadcast
  11 +void sendUDPBroadcast(unsigned char *message, int taille_message, int port) {
  12 + int broadcast_enable = 1;
  13 + //Option broadcast ON
  14 + int s = socket(AF_INET, SOCK_DGRAM, 0);
  15 + //Création de la socket : s = file descriptor de la socket, AF_INET (socket internet), SOCK_DGRAM (datagramme, UDP, sans connexion)
  16 + if(s < 0){
  17 + //Test de la valeur de retour de la socket
  18 + perror("sendUDPBroadcast.socket");
  19 + exit(-1);
  20 + }
  21 + if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &broadcast_enable, sizeof(broadcast_enable)) < 0) {
  22 + //Mise option broadcast à la socket
  23 + perror("sendUDPBroadcast.setsockopt");
  24 + exit(-1);
  25 + }
  26 +
  27 + struct sockaddr_in broadcast_address;
  28 + memset(&broadcast_address, 0, sizeof(broadcast_address));
  29 + broadcast_address.sin_family = AF_INET;
  30 + broadcast_address.sin_port = htons(port);
  31 + broadcast_address.sin_addr.s_addr = INADDR_BROADCAST; //255.255.255.255
  32 +
  33 + //Envoie du message grâce à la socket
  34 + if(sendto(s, message, taille_message, 0, (struct sockaddr *) &broadcast_address,
  35 + sizeof(broadcast_address)) < 0 ) {
  36 + perror("sendUDPBroadcast.sendto");
  37 + exit(-1);
  38 + }
  39 +}
  40 +
  41 +//Fonction permettant d'envoyer un message à une adresse
  42 +void sendUDPUnicast(char *address, unsigned char *message, int taille_message, int port) {
  43 + int s = socket(AF_INET, SOCK_DGRAM, 0);
  44 + //Création de la socket : s = file descriptor de la socket, AF_INET (socket internet), SOCK_DGRAM (datagramme, UDP, sans connexion)
  45 + if(s < 0){
  46 + //Test de la valeur de retour de la socket
  47 + perror("sendUDPUnicast.socket");
  48 + exit(-1);
  49 + }
  50 + struct sockaddr_in unicast_address;
  51 + //Creation structure adresse de destination
  52 + memset(&unicast_address, 0, sizeof(unicast_address));
  53 + //Mise à zéro de la structure d'adresse
  54 + unicast_address.sin_family = AF_INET;
  55 + unicast_address.sin_port = htons(port);
  56 + //Mise du port en ordre du réseau (big endian)
  57 + unicast_address.sin_addr.s_addr = inet_addr(address);
  58 + if(sendto(s, message, taille_message, 0, (struct sockaddr *) &unicast_address, sizeof(unicast_address)) < 0 ) {
  59 + perror("sendUDPUnicast.sendto");
  60 + exit(-1);
  61 + }
  62 +}
  63 +
  64 +int main(void){
  65 + unsigned char message_broadcast[100] = "J'envoie en UDP boradcast";
  66 + unsigned char message_unicast[100] = "J'envoie en UDP unicast";
  67 +
  68 + // send broadcast
  69 + sendUDPBroadcast(message_broadcast, strlen(message_broadcast), 2030);
  70 +
  71 + // send unicast
  72 + char adresse[50] = "127.0.0.1";
  73 + sendUDPUnicast(adresse, message_unicast, strlen(message_unicast), 2030);
  74 +
  75 + return 0;
  76 +}
0 77 \ No newline at end of file
... ...
UDP/Serveur/Makefile 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +
  2 +
  3 +all:
  4 + gcc main.c -o main.out
  5 +
  6 +exec: all
  7 + ./main.out
  8 +
  9 +clean:
  10 + rm -rf *.o *.out
0 11 \ No newline at end of file
... ...
UDP/Serveur/main.c 0 → 100644
... ... @@ -0,0 +1,87 @@
  1 +#include <stdio.h>
  2 +#include <stdlib.h> // pour exit()
  3 +#include <string.h>
  4 +#include <sys/types.h>
  5 +#include <sys/socket.h>
  6 +#include <netinet/in.h>
  7 +#include <netinet/ip.h>
  8 +#include <netinet/udp.h>
  9 +#include <netdb.h>
  10 +
  11 +#define BUFFER_SIZE 1000
  12 +
  13 +// Creation d'un serveur UDP
  14 +// service est le numéro ou nom de port (ex: "80" ou "http")
  15 +int initialisationServeurUDP(char *service){
  16 + struct addrinfo precisions, *resultat, *origine;
  17 + int statut;
  18 + int s;
  19 +
  20 + /* Construction de la structure adresse */
  21 + memset(&precisions, 0, sizeof precisions);
  22 + precisions.ai_family = AF_UNSPEC;
  23 + precisions.ai_socktype = SOCK_DGRAM;
  24 + precisions.ai_flags = AI_PASSIVE;
  25 + statut = getaddrinfo(NULL, service, &precisions, &origine);
  26 + if(statut < 0){ perror("initialisationSocketUDP.getaddrinfo"); exit(EXIT_FAILURE); }
  27 +
  28 + struct addrinfo *p;
  29 + for(p=origine, resultat=origine; p!=NULL; p=p->ai_next)
  30 + if(p->ai_family == AF_INET6){ resultat=p; break; }
  31 +
  32 + /* Creation d'une socket */
  33 + s = socket(resultat->ai_family, resultat->ai_socktype, resultat->ai_protocol);
  34 + if(s<0){ perror("initialisationSocketUDP.socket"); exit(EXIT_FAILURE); }
  35 +
  36 + /* Options utiles */
  37 + int vrai = 1;
  38 + if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &vrai, sizeof(vrai)) < 0){
  39 + perror("initialisationServeurUDPgenerique.setsockopt (REUSEADDR)");
  40 + exit(-1);
  41 + }
  42 +
  43 + /* Specification de l'adresse de la socket */
  44 + statut = bind(s, resultat->ai_addr, resultat->ai_addrlen);
  45 + if(statut < 0) { perror("initialisationServeurUDP.bind"); exit(-1); }
  46 +
  47 + /* Liberation de la structure d'informations */
  48 + freeaddrinfo(origine);
  49 +
  50 + return s;
  51 +}
  52 +
  53 +// Reception des messages UDP et execute la fonction passee en argument
  54 +// ATTENTION : non multi-threadé ! -> il faut un pthread_create dans traitement pour le multi-thread.
  55 +int boucleServeurUDP(int s, void (*traitement)(unsigned char *, int)){
  56 + while(1){
  57 + struct sockaddr_storage adresse;
  58 + struct sockaddr *padresse = (struct sockaddr *) &adresse;
  59 + socklen_t taille = sizeof(adresse);
  60 + unsigned char message[BUFFER_SIZE];
  61 +
  62 + int nboctets = recvfrom(s, message, BUFFER_SIZE, 0, (struct sockaddr *) padresse, &taille);
  63 + if(nboctets < 0) return -1;
  64 +
  65 + message[nboctets] = '\0';
  66 +
  67 + traitement(message, nboctets);
  68 + }
  69 + return 0;
  70 +}
  71 +
  72 +void exemple_traitement(unsigned char *message, int length){
  73 + (void) length; // on utilise pas length ici
  74 +
  75 + printf("Message recu :\n\n%s\n", message);
  76 +}
  77 +
  78 +int main(void){
  79 + // init serveur
  80 + char service[50] = "2030";
  81 + int socket = initialisationServeurUDP(service);
  82 +
  83 + // lancement boucle infinie
  84 + boucleServeurUDP(socket, exemple_traitement);
  85 +
  86 + return 0;
  87 +}
0 88 \ No newline at end of file
... ...