Bonjour the_guardian
L'aide de Borland C++ Builder c'est vraiment la misère et Google me renvoie sur des sites en japonais, allemand, roumain etc... A croire que les anglais et les français n'éprouvent pas le besoin de réinventer la poudre

Après de nouvelles recherches donc et pour prouver que je n'attends pas que les cailles tombent toutes roties J'ai commencé à écrire ça :
Mon projet ne gère que le GET et renvoie le(s) fichier(s) demandés.
Il renvoie la page "index.html" si rien n'a été précisé.
Il écoute sur le port 8080.
Marche pas trop mal si la page est "courte" et contient du texte seulement
Par contre si la page contient des liens vers des images ça fonctionne une fois sur 10

Index.html contient 2 images. Un GIF (smiley.gif) et un BMP (truc.bmp) pour voir...
Parfois les deux images arrivent, parfois 1 seule sinon aucune...
Quelquefois la même apparaît 2 fois et quelquefois elles sont inversées

(raaaahhhhh !)
En clair on est à des millions d'années lumières d'Apache et même un béotien comme moi ne saurait s'en contenter.
Voici la page index.html, ultra minimaliste
<html>
<head>
</head>
<body>
<P>Bienvenu</P>
<P>vous êtes connecté au serveur...
<img src="smiley.gif" width="320" height="344">
<img src="truc.bmp" width="352" height="288">
<hr>
</P>
</body>
</html>
voici le code Borland C++ Builder à mettre dans un form
Rem : le type du ServerSocket est "stNonBlocking". J'ai essayé l'autre valeur mais ça bloquait tout alors...
2 champs memos, une listbox pour les traces et faites rouler...
(désolé : je n'ai pas trouvé les balises utilisées sur le forum pour isoler le code du reste du message)
//---------------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <vcl.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
MemoIn->Lines->Clear();
ListBox1->Clear();
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
//...
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//Lancement du serveur
ServerSocket1->Active = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
ListBox1->Items->Add(AnsiString("ServerSocket1ClientConnect"));
ListBox1->Items->Add( Socket->RemoteAddress );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1Accept(TObject *Sender,
TCustomWinSocket *Socket)
{
//Evénement déclenché lorsque le serveur accepte une connexion
ListBox1->Items->Add(AnsiString("ServerSocket1Accept"));
AnsiString req;
char buf [1001], trav[256], textehtml [1001];
int lu;
//int lg = Socket->ReceiveLength();
req = "";
//Lecture de la requête du client
MemoIn->Lines->Add(AnsiString("---requete du navigateur------"));
do {
lu = Socket->ReceiveBuf(buf, sizeof(buf));
if (lu == -1)
break;
MemoIn->Lines->Add(AnsiString(buf));
req += AnsiString(buf);
} while (true);
MemoIn->Lines->Add(AnsiString("------------------------------"));
//pour l'instant on ne traite que GET : extraction du fichier demandé
int pos;
pos = AnsiPos("HTTP", req);
if (pos > 0)
req = req.SubString(1, pos-1);
pos = AnsiPos("GET /", req);
if (pos > 0)
req = req.SubString(pos+5, req.Length()-6);
req = Trim(req);
FichierDemande = req;
//On aiguille sur la page par défaut
if (FichierDemande == "")
FichierDemande = "index.html";
ListBox1->Items->Add(AnsiString("Fichier demandé: ")+FichierDemande);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1GetSocket(TObject *Sender, int Socket,
TServerClientWinSocket *&ClientSocket)
{
//Evénement
ListBox1->Items->Add(AnsiString("ServerSocket1GetSocket"));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientDisconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
//Evénement qui survient à la déconnexion du client.
ListBox1->Items->Add(AnsiString("ServerSocket1ClientDisconnect"));
ListBox1->Items->Add(AnsiString("-----------------------------"));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientWrite(TObject *Sender,
TCustomWinSocket *Socket)
{
ListBox1->Items->Add(AnsiString("ServerSocket1ClientWrite"));
TraiteRequete(Socket, FichierDemande);
Sleep (50); //sinon plante ?!?
Socket->Close(); //sinon ne reçoit jamais les données !?!
}
bool TForm1::TraiteRequete(TCustomWinSocket *Socket, AnsiString NomFichier)
{
AnsiString ext;
bool result;
//Recherche du type Mime (cf. http://hostmeister.com/mime.html)
result = false;
ext = UpperCase(ExtractFileExt(NomFichier));
if ( (ext == ".HTM") || (ext == ".HTML") )
result = EnvoiFichier(Socket, NomFichier, "text/html");
if ( (ext == ".JPG") || (ext == ".JPEG") )
result = EnvoiFichier(Socket, NomFichier, "image/jpeg");
if (ext == ".GIF")
result = EnvoiFichier(Socket, NomFichier, "image/gif");
if (ext == ".BMP")
result = EnvoiFichier(Socket, NomFichier, "image/bmp");
if ( (ext == ".EXE") || ( ext == ".CAB") )
result = EnvoiFichier(Socket, NomFichier, "application/octet-stream");
return result;
}
bool TForm1::EnvoiFichier(TCustomWinSocket *Socket, AnsiString NomFichier, AnsiString TypeFichier)
{
int id, lg;
char *bloc;
AnsiString entete;
bool resultat;
resultat = true;
id = open(NomFichier.c_str(), O_RDONLY|O_BINARY);
if (id != -1)
{
lg = filelength (id);
bloc = (char*)malloc (lg);
if (bloc != NULL)
{
lg = read (id, bloc, lg);
entete = "HTTP/1.0 200 OK\r\n";
entete += "Keep-Alive: timeout=15, max=100\r\n";
entete += "Connection: Keep-Alive\r\n";
entete += "Content-Type: " + TypeFichier + "\r\n";
entete += "Content-Length: " + AnsiString(lg) + "\r\n\r\n";
//Trace des entêtes envoyés
MemoOut->Lines->Add(entete);
MemoOut->Lines->Add(AnsiString("----------"));
int nbenvoi;
nbenvoi = Socket->SendBuf( entete.c_str(), entete.Length() );
Socket->SendBuf( bloc, lg );
free (bloc);
}
close (id);
}
return resultat;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1Listen(TObject *Sender,
TCustomWinSocket *Socket)
{
//Lancement du serveur
ListBox1->Items->Add(AnsiString("ServerSocket1Listen"));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ThreadEnd(TObject *Sender,
TServerClientThread *Thread)
{
ListBox1->Items->Add(AnsiString("ServerSocket1ThreadEnd"));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ThreadStart(TObject *Sender,
TServerClientThread *Thread)
{
ListBox1->Items->Add(AnsiString("ServerSocket1ThreadStart"));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1GetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket,
TServerClientThread *&SocketThread)
{
ListBox1->Items->Add(AnsiString("ServerSocket1GetThread"));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
ListBox1->Items->Add(AnsiString("ServerSocket1ClientError"));
if (ErrorEvent==eeGeneral)
ListBox1->Items->Add(AnsiString("'Erreur inattendue"));
if (ErrorEvent==eeSend)
ListBox1->Items->Add(AnsiString("Erreur écriture sur connexion socket"));
if (ErrorEvent==eeReceive)
ListBox1->Items->Add(AnsiString("Erreur lecture sur connexion socket"));
if (ErrorEvent==eeConnect)
ListBox1->Items->Add(AnsiString("'Demande connexion acceptée mais inachevée"));
if (ErrorEvent==eeDisconnect)
ListBox1->Items->Add(AnsiString("'Erreur fermeture connexion"));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
//Arrêt du serveur
ServerSocket1->Close();
}
//---------------------------------------------------------------------------