sioux.c
3.48 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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <pthread.h>
#define BUFF_SIZE 1000
int initialisationServeur(char* service)
{
int sock_fd;
struct addrinfo precisions, *resultat=NULL, *origine; // On stocke dans précisions nos besoins pour le socket, dans resultat l'adresse qui respectera les reqêtes
memset(&precisions, 0, sizeof precisions);
precisions.ai_family = AF_UNSPEC;
precisions.ai_socktype = SOCK_STREAM;
precisions.ai_flags = AI_PASSIVE;
if(getaddrinfo(NULL, service, &precisions, &origine)<0) { fprintf(stderr, "Erreur getaddrinfo\n"); return(-1); }
int n=0;
for(struct addrinfo* i=origine; i!=NULL && resultat==NULL; i=i->ai_next)
{
printf("%d - ", n);
if(i->ai_family==AF_INET)
{
resultat=i;
printf("Test : %d", origine->ai_addrlen);
}
printf("\n");
n++;
}
struct sockaddr_in* test=(struct sockaddr_in*)(resultat->ai_addr);
printf("Addr : %x\n", test->sin_addr.s_addr);
if((sock_fd=socket(resultat->ai_family, resultat->ai_socktype, resultat->ai_protocol))<0) { fprintf(stderr, "Erreur socket\n"); return(-1); }
int val=1;
if(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR|SO_BROADCAST, &val, sizeof(val))<0) { fprintf(stderr, "Erreur setsockopt\n"); return(-1); }
if(bind(sock_fd, resultat->ai_addr, resultat->ai_addrlen)) { fprintf(stderr, "Erreur bind\n"); return(-1); }
if(listen(sock_fd, 20) < 0) { fprintf(stderr, "Error listen server socket\n"); return (-1); }
freeaddrinfo(origine);
return sock_fd;
}
void* reponseConnexion(void* sock)
{
printf("Connected\n");
char buffer[BUFF_SIZE];
FILE* sockdial_stream = fdopen(*((int*)(sock)), "a+");
printf("Sock : %d // Stream : %p \n", *((int*)(sock)), sockdial_stream);
while(strcmp(buffer, "EXIT\n")!=0)
{
printf("WAIT\n");
fgets(buffer, BUFF_SIZE, sockdial_stream);
printf("Le message reçu : %s", buffer);
fprintf(sockdial_stream, "Ceci est une réponse du serveur TCP.\n");
}
strcpy(buffer, "START");
printf("Fin de la connexion\n");
fclose(sockdial_stream);
pthread_exit(NULL);
}
int lanceThread(void(* fonction) (void *), void* arg, int size)
{
pthread_t thr_id;
if(pthread_create(&thr_id, NULL, (void*)fonction, arg )!=0) { fprintf(stderr, "Le thread n'a pas pu être créé.\n"); return -1; }
pthread_detach(thr_id);
return 0;
}
int boucleServeur(int socket, void(* fctConnex)(int))
{
int sock_dial;
printf("------- Début boucle serveur TCP -------\n\n");
while(1)
{
printf("-- boucle --\n");
if((sock_dial=accept(socket, NULL, NULL)) < 0){ fprintf(stderr, "Error accept dialogue\n"); return -1; }
printf("Dialogue ACCEPTED\n");
lanceThread((void*)fctConnex, (void*)&sock_dial, sizeof(sock_dial));
}
}
void argPortParsing(int argc, char* argv[], char* port)
{
struct option port_arg={"port", 1, NULL, 'p'};
char opt;
int longindex;
while( (opt=getopt_long(argc, argv, "p:", &port_arg, &longindex)) !='p' && opt!=-1) {}
if(opt=='p')
{
strcpy(port, optarg);
printf("%s\n", optarg);
}
else
{
printf("La syntaxe doit être de la forme ./sioux -p <port> ou ./sioux --port <port>\n\n");
}
}
int main(int argc, char* argv[])
{
char port[10]="80";
argPortParsing(argc, argv, port);
int sock_fd=initialisationServeur(port);
if( sock_fd==-1 ) { fprintf(stderr, "Initialisation du serveur impossible\n"); return -1; }
boucleServeur(sock_fd, (void*)&reponseConnexion);
return 0;
}