Bonjour,
Voila je programme un petit serveur HTTP (sous Windows) multi-thread (pthread) et ce dernier plante misérablement, ca fait un moment que je cherche d'où vient l'erreur mais je n'arrive pas a trouver.
je poste le code complet :
Header.h
main.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 ifndef HEADER_H_INCLUDED #define HEADER_H_INCLUDED #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <pthread.h> #include <sys/stat.h> struct cli { pthread_t thread; SOCKADDR_IN sin; int recsize; SOCKET sock; }; void* Thread_Client(void* data); int pHTTP (void* data, char* Request); int Send_HTTP_Reply (void* data, int err); int Send_HTML_File(char *Path,void* data); int Send_File (void* data, char* Path); #endif // HEADER_H_INCLUDED
Thread.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 #include "Header.h" int main() { WSADATA wsa_data; WSAStartup (MAKEWORD (2, 2), &wsa_data); SOCKET sock = socket (AF_INET, SOCK_STREAM, 0); SOCKADDR_IN sin = {0}; sin.sin_addr.s_addr = htonl (INADDR_ANY); sin.sin_family = AF_INET; sin.sin_port = htons (80); bind (sock, (SOCKADDR *) &sin, sizeof sin); listen (sock, 5); struct cli *p_cli = NULL; do // Boucle { p_cli = malloc (sizeof *p_cli); if (p_cli != NULL) { p_cli->recsize = (int) sizeof p_cli->sin; p_cli->sock = accept (sock, (SOCKADDR *) &p_cli->sin, &p_cli->recsize); if (p_cli->sock != INVALID_SOCKET) // Client connecte .. { printf("Client connected with socket %d from %s:%d\n", p_cli->sock, inet_ntoa (p_cli->sin.sin_addr), htons (p_cli->sin.sin_port)); pthread_create(&p_cli->thread,NULL,Thread_Client,p_cli); p_cli = NULL; } } else { puts("Error : memory allocation"); } }while(1); WSACleanup (); return 0; }
HTTP.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 #include "Header.h" void* Thread_Client(void* data) { char Buff[512] = {0}; fd_set fdsr; struct timeval tv_timeout; int nb_bytes; struct cli *p_cli = data; if (p_cli == NULL) { puts("Error : Memory allocation"); return NULL; } pthread_detach(p_cli->thread); FD_ZERO(&fdsr); FD_SET(p_cli->sock,&fdsr); tv_timeout.tv_sec = 2; tv_timeout.tv_usec = 0; // Timeout if (select(p_cli->sock+1,&fdsr,NULL,NULL,&tv_timeout) <= 0) { printf("Timeout %s:%d\n", inet_ntoa (p_cli->sin.sin_addr),htons (p_cli->sin.sin_port)); goto end; } if (FD_ISSET(p_cli->sock, &fdsr)) // Si reception de données.. { // Reception de la Requette HTTP du client nb_bytes = recv(p_cli->sock,Buff,sizeof(Buff),0); if(nb_bytes > 0) // Si supérieur a 0 Byte { // Gestion du protocole HTTP .. if(pHTTP(p_cli, Buff) != 0) { puts("Intern Error"); } } else { printf("Error recv \n"); } } end: closesocket(p_cli->sock); p_cli->sock = INVALID_SOCKET; free(p_cli); p_cli = NULL; pthread_exit(0); return NULL; }
Reply.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
157
158
159
160
161
162
163
164
165
166
167
168
169 #include "Header.h" int Test_File(char* Path) { FILE * file = NULL; file = fopen(Path,"rb"); if(file == NULL) { return 0; } fclose(file); return 1; } char* Format(char *Request, char *Path) { char *ptr = NULL; int i = 0; ptr = strstr(Request,"/"); if(ptr != NULL) { ptr++; sprintf(Path,"%s",ptr); while (Path[i] != ' ') { i++; } Path[i] = 0; return Path; } return NULL; } int pHTTP (void* data, char* Request) { char Path[50] = {0}; unsigned char *ptr; struct cli *p_cli = data; if (p_cli == NULL) { puts("Error : memory allocation"); return 1; // Internal Server Error } // -- Test Version du protocol HTTP --- ptr = NULL; ptr = strstr(Request,"HTTP/1.1"); if(ptr == NULL) // Si la version utilisé par le client n'est pas 1.1 { puts("400 Bad Request"); Send_HTTP_Reply(p_cli,400); Send_HTML_File("Bad_Request.html",p_cli); free(ptr); return 0; } //------------------------------------ else // Si la version 1.1 est utilisée { //---------[GET METHOD]-------------------- ptr = NULL; ptr = strstr(Request,"GET"); // Si methode GET du protocol HTTP if(ptr != NULL) { //------------[Demande page index.html]--------------------------- ptr = NULL; ptr = strstr(Request,"/ HTTP/1.1"); // Si demande page index.html if(ptr != NULL) { printf("%s:%d - HTTP GET METHOD - index.html\n",inet_ntoa (p_cli->sin.sin_addr),htons (p_cli->sin.sin_port)); if(Test_File("index.html") == 1) // Sil le fichier index.html est existant { Send_HTTP_Reply(p_cli,200); if (Send_HTML_File("index.html",p_cli) == 1) { puts("Intern_Error"); Send_HTTP_Reply(p_cli,500); Send_HTML_File("Intern_Error.html",p_cli); free(ptr); return 0; } } else // Fichier introuvable .. { puts("404 NOT FOUND"); Send_HTTP_Reply(p_cli,404); //404 Send_HTML_File("Not_Found.html",p_cli); free(ptr); return 0; // Erreur interne car manque fichier principal html } } // if index.html //-------------------[Demande fichier .jpg]------------------------- ptr = NULL; ptr = strstr (Request,".jpg"); // Si demande fichier .jpg if(ptr != NULL) { ptr = NULL; ptr = strstr(Request,"images/"); // Restriction if (ptr != NULL) { // Format request .. if (Format(Request,Path) != NULL) { if(Test_File(Path) == 1) { printf("%s:%d - HTTP GET METHOD - %s\n",inet_ntoa (p_cli->sin.sin_addr),htons (p_cli->sin.sin_port),Path); if (Send_File(p_cli,Path) != 0) { puts("error Send_File"); Send_HTTP_Reply(p_cli,500); Send_HTML_File("Intern_Error.html",p_cli); free(ptr); return 1; } else { printf("fichier envoye\n"); free(ptr); return 0; } } else { puts("404 NOT FOUND"); Send_HTTP_Reply(p_cli,404); Send_HTML_File("Not_Found.html",p_cli); free(ptr); return 0; } } else // Erreur intern, impossible de récupérer la Path { puts("Intern_Error 500"); Send_HTTP_Reply(p_cli,500); Send_HTML_File("Intern_Error.html",p_cli); free(ptr); return 0; } } else // Non respect de la restriction { puts("400 Bad Request"); Send_HTTP_Reply(p_cli,400); //400 Send_HTML_File("Bad_Request.html",p_cli); free(ptr); return 0; } } // if .jpg } // if get } return 0; }
Dans le répertoire de mon exe j'ai une page html toute simple
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 #include "Header.h" // Envoyer reponse HTTP au client int Send_HTTP_Reply (void* data, int err) { char Buff[70] = {0}; struct cli *p_cli = data; if (p_cli == NULL) { puts("Error : memory allocation"); return 1; } switch(err) { case 400: sprintf(Buff,"HTTP/1.1 400 BAD REQUEST\r\n"); break; case 404: sprintf(Buff,"HTTP/1.1 404 NOT FOUND\r\n"); break; case 500: sprintf(Buff,"HTTP/1.1 500 Internal Server Error\r\n"); break; case 200: sprintf(Buff,"HTTP/1.1 200 OK\r\n"); break; } send(p_cli->sock,Buff,strlen(Buff)+1,0); send(p_cli->sock,"Content-Type : text/HTML\r\n\r\n",strlen("Content-Type : text/HTML\r\n\r\n")+1,0); return 0; } // Envoi d'un fichier HTML int Send_HTML_File(char *Path,void* data) { struct stat stat_struct; char Page[500] = {0}; struct cli *p_cli = data; if (p_cli == NULL) { puts("Error : memory allocation"); return 1; } FILE *HTML = NULL; HTML = fopen(Path,"rb"); if(HTML != NULL) { stat(Path,&stat_struct); while(fgets(Page,stat_struct.st_size,HTML) != NULL) { send(p_cli->sock,Page,strlen(Page)+1,0); memset(Page,0,sizeof(Page)); } fclose(HTML); } else { return 1; } return 0; } int Send_File (void* data, char* Path) { FILE *file = NULL; int read = 0; char Buffer[512] = {0}; struct cli *p_cli = data; if (p_cli == NULL) { puts("Error : memory allocation"); return 1; } file = fopen(Path,"rb"); if (file != NULL) { do{ read = fread(Buffer,1,512,file); send(p_cli->sock,Buffer,read,0); memset(Buffer,0,sizeof(Buffer)); if (read < 512) { fclose(file); break; } }while (1); } else { return 1; // Error } return 0; }
nommée 'index.html', elle utilise une image de fond
(<body background = "images/fond.jpg">).
Le programme se crash si le client demande l'image, si je commente dans mon code html la balise body, le serveur ne plante pas..
Si quelqu'un peut me dire ce qu'il se passe, merci d'avance.
Partager