main.c
3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <stdio.h>
#include <stdlib.h> // pour exit()
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netdb.h>
#define BUFFER_SIZE 1000
#define MAX_TCP_CONNEXION 5
// Fonction permettant de créer le serveur TCP
// service est le numéro ou nom de port (ex: "80" ou "http")
int initialisationServeurTCP(char *service){
struct addrinfo precisions, *resultat, *origine;
int statut;
int s;
/* Construction de la structure adresse */
memset(&precisions, 0, sizeof precisions);
precisions.ai_family = AF_UNSPEC;
precisions.ai_socktype = SOCK_STREAM;
precisions.ai_flags = AI_PASSIVE;
statut = getaddrinfo(NULL, service, &precisions, &origine);
if(statut < 0){
perror("initialisationSocketTCP.getaddrinfo");
exit(EXIT_FAILURE);
}
struct addrinfo *p;
for(p = origine, resultat = origine; p != NULL; p = p->ai_next) {
if(p->ai_family == AF_INET6){
resultat = p;
break;
}
}
/* Creation d'une socket */
s = socket(resultat->ai_family, resultat->ai_socktype, resultat->ai_protocol);
if(s < 0){
perror("initialisationSocketTCP.socket");
exit(EXIT_FAILURE);
}
/* Options utiles */
int vrai = 1;
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &vrai, sizeof(vrai))<0) {
perror("initialisationServeurTCPgenerique.setsockopt (REUSEADDR)");
exit(-1);
}
/* Specification de l'adresse de la socket */
statut = bind(s, resultat->ai_addr, resultat->ai_addrlen);
if(statut<0) {
perror("initialisationServeurTCP.bind");
exit(-1);
}
/* Liberation de la structure d'informations */
freeaddrinfo(origine);
/* Taille de la queue d'attente */
statut = listen(s, MAX_TCP_CONNEXION);
if(statut < 0)
return -1;
return s;
}
// Accepte toutes les connexions au serveur TCP et execute la fonction en argument
// ATTENTION : non multi-threadé ! -> il faut un pthread_create dans traitement pour le multi-thread.
int boucleServeurTCP(int socket, void (*traitement)(int)){
while(1){
// accept connection
struct sockaddr ip_src;
socklen_t ip_len = sizeof(struct sockaddr);
int socket_dialogue = accept(socket, &ip_src, &ip_len);
if(socket_dialogue < 0){
perror("boucleServeur.accept");
return -1;
}
// callback function
traitement(socket_dialogue);
}
return 0;
}
void exemple_traitement(int socket){
FILE *dialogue = fdopen(socket, "a+");
if(dialogue==NULL){ perror("gestionClientHTTP.fdopen"); exit(-1); }
char line[BUFFER_SIZE];
char *success = fgets(line, BUFFER_SIZE, dialogue);
if(success == NULL){
fclose(dialogue);
return;
}
printf("Message recu :\n\n%s\n", line);
fprintf(dialogue, "Message recu :\n\n%s\n", line);
fclose(dialogue);
}
int main(void){
// init serveur
char service[50] = "2030";
int socket = initialisationServeurTCP(service);
// lancement boucle infinie
boucleServeurTCP(socket, exemple_traitement);
return 0;
}