Bonjour,
Je débute en C++, et j'ai pour projet de développer un petit serveur Web ...
J'ai donc commencé à coder un petit serveur multithreads telnet pour tester les multiconnexions.
Tout semblait fonctionnner correctement.
En revanche lors de l'implémentation du protocole HTTP, j'ai un bug donc je ne trouve pas la solution :
- lors de l'affichage d'une page contenant plusieurs images, certaines ne s'affichent pas. En faisant "actualiser" plusieurs fois on peut obtenir un résultat...
Quelqu'un pourrait il m'aider ??
Code :
// les lib ...
#include <cstdlib>
#include <iostream>
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include "definitions.h"
#pragma comment(lib, "ws2_32.lib")
using namespace std;
// type def ...
typedef struct{
SOCKADDR_IN sin_sock;
SOCKET clien_sock;
}param_sock;
// prototypes ...
static DWORD WINAPI ThreadLauncher(void *param);
// les classes ...
class HTTPServer {
// private :
int sinsize;
int Port;
SOCKET sock;
SOCKET csock;
SOCKADDR_IN sin, csin;
WSADATA WSAData;
public :
// constructeur ...
HTTPServer(int leport)
{
this->Port = leport;
}
// attendre connexion ...
void Start()
{
char log_ip[1024];
DWORD ThreadId;
// CLIENT_TYP ac;
HANDLE HandleThread;
int curT = 0;
param_sock client;
WSAStartup(MAKEWORD(2,0), &WSAData);
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_family = AF_INET;
sin.sin_port = htons(Port);
bind(sock, (SOCKADDR *)&sin, sizeof(sin));
listen(sock, 0);
sinsize = sizeof(csin);
while(1)
{
if((csock = accept(sock, (SOCKADDR *)&csin, &sinsize)) != INVALID_SOCKET)
{
sprintf(log_ip, "\n Connexion de : %s",inet_ntoa(csin.sin_addr));
//log_querry(log_ip);
printf("%s", log_ip);
client.clien_sock = csock;
client.sin_sock = csin;
HandleThread = CreateThread(NULL, 0, &ThreadLauncher, &client, 0, NULL);
}else printf("\n\n Une connexion à buggé !!, port %d\n\n", Port);
}
}// fin start !
DWORD ClientThread(SOCKET soc){
char buffer[4096];
int received=0;
char to_send[] = "test\n";
char url[2048];
char url2send[2048];
char entete[2048];
FILE *file;
char buff[BUFFSIZE];
size_t nb_lu=0;
int i=0;
/*
for(i=0;i<sizeof(buffer);i++) buffer[i]=0;
for(i=0;i<sizeof(url);i++) url[i]=0;
for(i=0;i<sizeof(url2send);i++) url2send[i]=0;
for(i=0;i<sizeof(entete);i++) entete[i]=0;
for(i=0;i<sizeof(buff);i++) buff[i]=0;
*/
memset(buffer, '\0', sizeof(buffer));
memset(url, '\0', sizeof(url));
memset(url2send, '\0', sizeof(url2send));
memset(entete, '\0', sizeof(entete));
memset(buff, '\0', sizeof(buff));
//send(soc, to_send, sizeof(to_send), 0);
//cout << "SOCKET :: " << param.clien_sock << " ." << endl;
//cout << "\nsoc" << soc << endl;
// while(1)
// {
if((received = recv(soc, buffer, sizeof(buffer), 0)) > 0)
{
buffer[received] = '\0';
//printf("%s", buffer);
// cout << "\n\t" << " => DATA : " << buffer <<" ..." << endl;
sscanf(buffer,"GET %s", &url);
// cout << "[URL] :: " << url << endl;
if(strcmp(url, "/") == 0)
{
// send(soc,entete_from_file(url), strlen(entete_from_file(url)), 0);
// sprintf(entete, "%s\0" ,entete_from_file("index.html"));
// cout << "entete : " << entete_from_file("index.html") << " len : " << strlen(entete_from_file("index.html")) << endl;
sprintf(url2send, "www/index.html");
send(soc,entete_from_file("index.html"), strlen(entete_from_file("index.html")), 0);
send_html(soc, "www/index.html");
cout << "[URL] :: " << url << endl;
}else{
sprintf(url2send, "www%s", url);
send(soc,entete_from_file(url2send), strlen(entete_from_file(url2send)), 0);
send_html(soc, url2send);
cout << "[URL] :: " << url2send << endl;
cout << "--------------------------\nentete : " << entete_from_file(url2send) << " len : " << strlen(entete_from_file(url2send)) << "\n----------------------" << endl;
}
}
// cout << "Error receive !" << endl;
// }
closesocket(soc);
return 0;
}
char *entete_from_file(char url[URL_SIZE]){
char tmp[URL_SIZE];
char ext[URL_SIZE];
int i, j, k;
char entete[4096];
char html_type[] = "html";
char rcb_type[] = "rcb";
char gif_type[] = "gif";
char jpg_type[] = "jpg";
i = strlen(url);
j=0;
k=0;
/*
for(i=0;i<sizeof(tmp);i++) tmp[i]=0;
for(i=0;i<sizeof(ext);i++) ext[i]=0;
for(i=0;i<sizeof(entete);i++) entete[i]=0;
*/
memset(tmp, '\0', sizeof(tmp));
memset(ext, '\0', sizeof(ext));
memset(entete, '\0', sizeof(entete));
// on part de la fin, on s'arrete au point
while((url[i] != '.') && i > 0)
{
tmp[j] = url[i];
i--;
j++; // j est la longueur de tmp ;)
}
// on remet l'extension à l'endrois
while(j>0)
{
j--;
ext[k] = tmp[j];
k++;
}
// sprintf(entete,"HTTP/0.9 200 OK\n\r\n");
entete[0]='\0';
if(strcmp(html_type, ext) == 0) sprintf(entete,"HTTP/0.9 200 OK\nServer : Romcyber\nContent-Type : %s\r\n\r\n", HTTP_ENTETE_HTML);
if(strcmp(rcb_type, ext) == 0) sprintf(entete,"HTTP/0.9 200 OK\nServer : Romcyber\nContent-Type : %s\r\n\r\n", HTTP_ENTETE_HTML);
if(strcmp(gif_type, ext) == 0) sprintf(entete,"HTTP/0.9 200 OK\nServer : Romcyber\r\nConnection: close\r\nContent-Type : %s\r\n\r\n", HTTP_ENTETE_GIF);
if(strcmp(jpg_type, ext) == 0) sprintf(entete,"HTTP/0.9 200 OK\nServer : Romcyber\nContent-Type : %s\r\n\r\n", HTTP_ENTETE_JPG);
if(strlen(entete)<1) sprintf(entete,"HTTP/0.9 200 OK\nServer : Romcyber_V1.1\nContent-Type : %s\r\n\r\n", HTTP_ENTETE_ELSE);
return entete;
}
int send_html(SOCKET sock, char fichier[URL_SIZE]){
FILE *file;
char buff[BUFFSIZE];
int nb_lu=0;
int i;
//for(i=0;i<sizeof(buff);i++) buff[i]=0;
memset(buff, '\0', sizeof(buff));
//send(sock, "\r\n", 2, 0);
// sendfile(sock, fichier);
// send(sock, CRLF, strlen(CRLF), 0);
// send(sock, CRLF, strlen(CRLF), 0);
if((file = fopen(fichier,"rb")) != NULL){
while(!feof(file)){
for(i=0; i<sizeof(buff);i++) buff[i]=0;
nb_lu = fread(buff,1, sizeof(buff), file); //sizeof(buff)
send(sock, buff, nb_lu, 0);
// cout << buff << endl;
}
// send(sock, CRLF, strlen(CRLF), 0);
// send(sock, CRLF, strlen(CRLF), 0);
fclose(file);
return 1;
}else
{
send(sock, "<H1>ERROR 404 : NOT FILE FOUND.</H1>", strlen("<H1>ERROR 404 : NOT FILE FOUND.</H1>"), 0);
return 404;
}
// send(sock, "\r\n", 2, 0);
// send(sock, "\r\n", 2, 0);
}
};
static DWORD WINAPI ThreadLauncher(void *param)
{
// SOCKET client = (SOCKET)param;
//param_sock client = (param_sock)param;
param_sock *client = reinterpret_cast<param_sock*>(param);
HTTPServer *s;
return s->ClientThread(client->clien_sock);
}
// fin recevoir !
int main(int argc, char *argv[])
{
HTTPServer s1(HTTP_PORT);
cout << "Démarrage serveur HTTP 1 : " << rand() << rand() << rand() << endl;
s1.Start();
system("PAUSE");
return EXIT_SUCCESS;
}
merci
kilomaster [url]mailto:romcy91@msn.com[/url]