C++cuilder - charger un bitmap depuis une adresse ip

Signaler
Messages postés
5
Date d'inscription
mercredi 22 septembre 2010
Statut
Membre
Dernière intervention
11 janvier 2011
-
Messages postés
5
Date d'inscription
mercredi 22 septembre 2010
Statut
Membre
Dernière intervention
11 janvier 2011
-
Bonjour à tous

Projet C++ Builder 6 :
* connection par adresse ip à une camera
(serveur) (par exemple 192.168.3.13, puis
* extraction d'une image par adresse http
exemple: /content/image.jpg

Il ne s'agit pas d'afficher l'image jpg dans une page internet, mais de la charger directement en mémoire (buffer) pour la convertir en bitmap pour lui faire subir quelques traitements numérique (éventuellement l'affichée dans un canvas avant ou après traitement)

je suis persuadé que C++ Builder 6 peu resoudre ce type d'application relativement simplement avec les fonctions associées aux sockets. Cependant je rencontre quelques problèmes car la doc en ligne Borland et les manuels dont je dispose (C++ Builder 3) ne me fournissent pas assez d'infos pour avancer.

je me connecte bien à la camera avec le socket, mais je n'ai pas vraiment trouvé le moyen de capter le flux TCP/IP / http pour en extraire le contenu du fichier image jpg correspondant.

Quelqu'un aurait-il une solution, ou l'expérience de ce type d'application.
Merci pour votre aide.

Evidemment la solution complète sera publiée en retour pour tout ceux qui pourraient avoir besoin d'une solution analogue.

Marc

7 réponses

Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
11
Bonjour,

On est bien d'accord qu'il s'agit d'une jpg, donc d'une image fixe (Pas de la vidéo) ?

Genre une webcam de station, par exemple comme ça.

Si tu télécharge le code de la page, tu n'as en fait pas l'image qui est téléchargée ultérieurement (Le navigateur télécharge le code de la page, voit qu'il y a une image à afficher, télécharge l'image et l'affiche.

Dans le code de la page de mon lien, voici la partie sur la photo.




C'est l'url src, et non l'url de la page, qui t'intéresse. D'ailleurs si dans ton navigateur tu entres cette rl tu tombes sur l'image seule.

Donc si tu fais une requête GET à l'aide de C++ Builder sur l'url de l'image tu devrais belle et bien récupérer l'image et non de l'HTML (Content-Type: image/jpeg).

Niveau doc, normalement, il y en a de fournit avec C++ Builder 6. Et il y en a sur ce site aussi, par exemple ici.
Messages postés
5
Date d'inscription
mercredi 22 septembre 2010
Statut
Membre
Dernière intervention
11 janvier 2011

On est d'accord qu'il s'agit d'une jpg.
l'adresse exacte d'accès est d'ailleurs celle-ci:
http://192.168.3.13/record/current.jpg

il s'agit de passer cette adresse au serveur ( http://192.168.3.13/ )afin qu'il transmette l'image et de la récupérer directement en mémoire pour la traiter.

Apparemment la requette Get fait partie du composant NMHTTP et ce composant ne semble pas installé (fastNet) dans mon c++builder.

La camera attend probablement des éléments de code tcp/ip et html que je ne sais pas lui transmettre par le socket.

pour être certain de ne rien manquer j'ai intégré une fonction d'affichage en Hexa du buffer de réception du programme "client".
Après connexion et en lui passant ou non l'adresse de l'image, le serveur (la camera) renvoie un message et ferme la connexion au bout de 60 secondes :

HTTP/1.0 408 Request Timeout
Server: thttpd/2.19-MX Jul 5 2010
Content-type: text/html
Date: Wed, 10 Nov 2010 01:10:05 GMT
Last-modified: Wed, 10 Nov 2010 01:10:05 GMT
Accept-Ranges: bytes
Connection: close

<HTML><HEAD><TITLE>408 Request Timeout</TITLE></HEAD>
408 Request Timeout

No request appeared within a reasonable time period.
<HR>
thttpd/2.19-MX Jul 5 2010</HTML>


la fonction send de mon client ne semble pas être comprise ou reçue par le serveur.

void __fastcall TClient::SendClick(TObject *Sender)
{
if( ClientSocket1->Active )
ClientSocket1->Socket->SendText(EdSend->Text);
else {
LbCState->Caption = " Serveur Client à L'arret ";
LbCState->Color=clRed;
LbCState->Font->Color=clWhite;
BnConnect->Caption= "Activer";
}
}


fonction réception :
void __fastcall TClient::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
// EdReceive->Text=ClientSocket1->Socket->ReceiveText();

AnsiString Data;
Data.SetLength(Socket->ReceiveLength());
Socket->ReceiveBuf(Data.c_str(),Socket->ReceiveLength());
ShowMessage(Socket->RemoteHost+": "+Data);
Memo1->Text=Data; //
}
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
11
Il doit y avoir a peu près un million de composants Delphi/C++ Builder permettant de faire des requêtes HTTP. L'un des plus connus est Indy.

Récupération d'image via Indy.

Bon, après, tout ça est surtout utilisé en Delphi... Je n'ai moi même pas C++ Builder. Mais la traduction des codes Delphi ne devrait pas te poser trop de problème : les noms des méthodes et les propriétés sont les mêmes.

Passer directement par une TSocketClient devrait fonctionner aussi quoique plus compliqué : Il faut gérer la couche HTTP à la main. Doc HTTP ici.

Et voici de l'aide sur TSocketClient.

D'après le message d'erreur, il semble effectivement que t'as requête soit incomplète ou pas du tout envoyée. Qu'as tu mis dans EdSend->Text ?

Voilà un code complet (Mais Delphi) qui fonctionne sur l'image de mon lien plus haut.
Une form avec un bouton btnGo, un memo memResponseHeader, une image imgResult et une TSocketClient socMain.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls, StrUtils, ExtCtrls, Jpeg, Buttons;

type
  TForm1 = class(TForm)
    btnGo: TButton;
    memResponseHeader: TMemo;
    imgResult: TImage;
    socMain: TClientSocket;
    procedure btnGoClick(Sender: TObject);
    procedure socMainRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure socMainConnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure FormCreate(Sender: TObject);
    procedure socMainError(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
  private
    _lpResponse: String;
    _bReadingHeader: Boolean;
    _nContentLength: Integer;
    _lpContentStream: TMemoryStream;
    function GetContentLength(lpHeader: String): Integer;
    function CheckResponse(lpHeader: String): Boolean;
    procedure DisplayImage();
    procedure CleanUp();
  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btnGoClick(Sender: TObject);
begin
  btnGo.Enabled:= False;
  _lpResponse:= '';
  _bReadingHeader:= True;
  _lpContentStream:= nil;
  socMain.Open;
end;

procedure TForm1.socMainError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  if ErrorEvent = eeGeneral then
    ShowMessage('Erreur inattendu');

  if ErrorEvent = eeSend then
    ShowMessage('Erreur d''écriture sur la connexion socket');

  if ErrorEvent = eeReceive then
    ShowMessage('Erreur de lecture sur la connexion socket');

  if ErrorEvent = eeConnect then
    ShowMessage('Une demande de connexion déjà acceptée n''a pas pu être achevée');

  if ErrorEvent = eeDisconnect then
    ShowMessage('Erreur de fermeture d''une connexion');

  if ErrorEvent = eeAccept then
    ShowMessage('Erreur d''acceptation d''une demande de connexion cliente');

  CleanUp;
end;

function TForm1.GetContentLength(lpHeader: String): Integer;
var
  nContentLengthPos: Integer;
  lpContentLengthString: String;
  nEndOfLinePos: Integer;
begin
  Result:= 0;

  // Récupération du début le Content-Length
  nContentLengthPos:= Pos('Content-Length:', lpHeader);
  if nContentLengthPos = 0 then
    Exit;
  lpContentLengthString:= MidStr(lpHeader, nContentLengthPos, High(Integer));

  // Troncature de ce qui se trouve après le Content-Length
  nEndOfLinePos:= Pos(#13#10, lpContentLengthString);
  if nEndOfLinePos = 0 then
    nEndOfLinePos:= Pos(#10, lpContentLengthString);
  lpContentLengthString:= LeftStr(lpContentLengthString, nEndOfLinePos - 1);

  // Récupération de la valeur
  lpContentLengthString:= StringReplace(lpContentLengthString, 'Content-Length:', '', [rfReplaceAll, rfIgnoreCase]);
  lpContentLengthString:= Trim(lpContentLengthString);
  Result:= StrToInt(lpContentLengthString);
end;

function TForm1.CheckResponse(lpHeader: String): Boolean;
var
  nEndOfLinePos: Integer;
  lpStatus: String;
begin
  nEndOfLinePos:= Pos(#13#10, lpHeader);
  if nEndOfLinePos = 0 then
    nEndOfLinePos:= Pos(#10, lpHeader);
  lpStatus:= LeftStr(lpHeader, nEndOfLinePos - 1);

  Result:= Pos('200 OK', lpStatus) <> 0;
end;

procedure TForm1.DisplayImage();
var
  lpJpg: TJPEGImage;
begin
  lpJpg:= TJPEGImage.Create;
  _lpContentStream.Position:= 0;
  lpJpg.LoadFromStream(_lpContentStream);
  imgResult.Picture.Assign(lpJpg);
  lpJpg.Free;
  CleanUp;
end;

procedure TForm1.CleanUp();
begin
  FreeAndNil(_lpContentStream);
  socMain.Close;
  btnGo.Enabled:= True;
end;

procedure TForm1.socMainRead(Sender: TObject; Socket: TCustomWinSocket);
var
  nEndOfHeader: Integer;
  nEndOfHeaderSize: Integer;
  lpReceivedText: String;
  lpHeader: String;
  lpContent: ^Char;
  nReadContent: Integer;
  nReceived: Integer;
begin
  nReceived:= Socket.ReceiveLength;
  lpReceivedText:= Socket.ReceiveText;

  // Si le header n'a pas encore été complètement lu
  if _bReadingHeader then
  begin
    _lpResponse:= _lpResponse + lpReceivedText;

    // Recherche de \r\n\r\n
    nEndOfHeaderSize:= 4;
    nEndOfHeader:= Pos(#13#10#13#10, _lpResponse);

    // Recherche de \n\n
    if nEndOfHeader = 0 then
    begin
      nEndOfHeaderSize:= 2;
      nEndOfHeader:= Pos(#10#10, _lpResponse);
    end;

    // Si au moins tout le header est arrivé
    if nEndOfHeader <> 0 then
    begin
      _bReadingHeader:= False;

      // Extraction du header
      lpHeader:= LeftStr(_lpResponse, nEndOfHeader + nEndOfHeaderSize - 1);
      memResponseHeader.Text:= lpHeader;

      // Vérification que c'est bien une réponse 200 OK
      if not CheckResponse(lpHeader) then
      begin
        ShowMessage('Mauvais status code');
        Exit;
      end;

      // Rcupération de la taille du content, donc de la jpg
      _nContentLength:= GetContentLength(lpHeader);

      lpContent:= @_lpResponse[nEndOfHeader + nEndOfHeaderSize];

      nReadContent:= Length(_lpResponse) - Length(lpHeader);

      _lpContentStream:= TMemoryStream.Create;
      _lpContentStream.Write(lpContent^, nReadContent);
    end;
  end
  else
    _lpContentStream.Write(PChar(lpReceivedText)^, nReceived);

  // On affiche l'image quand on a reçu tout le content
  if _lpContentStream <> nil then
    if _lpContentStream.Position = _nContentLength then
      DisplayImage;
end;

procedure TForm1.socMainConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  socMain.Socket.SendText('GET http://www.trinum.com/ibox/ftpcam/rosiere_traversette.jpg HTTP/1.0' + sLineBreak + sLineBreak);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  socMain.Host:= 'www.trinum.com';
  socMain.Port:= 80;
end;

end.
Messages postés
5
Date d'inscription
mercredi 22 septembre 2010
Statut
Membre
Dernière intervention
11 janvier 2011

Merci pour le support technique. 

Quelques soucis ont retardé ma réponse. 

j'ai pu installer indy 9.0.18 dans mon c++Buider6, et récupéré un exemple d'utilisation de la fonction Get de IdHTTP mais j'ai eu une erreur jpeg 41. 

Par contre, mon bout d'essai avec les sockets fonctionne presque. il manquait simplement une ligne de commande dans le protocole http 

Ma requête n'envoyais que l'adresse de mon image sans envoyer la ligne Accept. 
GET /record/current.jpg HTTP/1.0"; 
Accept image/jpeg; 
(cr/lf)



La réception du socket semble fonctionner correctement. Elle utilise un memo : MemoText et une procédure Display celle-ci affiche les paquets renvoyés en hexa décimal. 

Seul problème ReceiveLength() ne donne pas le nombre réel d'octets du paquet mais une valeur plus faible. Dès que j'aurais trouvé la solution à ce dernier problème le paquet reçu (=jpeg) pourra être converti en bitmap. 

void __fastcall TClient::ClientSocket1Read(TObject *Sender, 
TCustomWinSocket *Socket) 

// EdReceive->Text=ClientSocket1->Socket->ReceiveText(); 

AnsiString Data; 
Data.SetLength(Socket->ReceiveLength()); 
Socket->ReceiveBuf(Data.c_str(),Socket->ReceiveLength()); 
//ShowMessage(Socket->RemoteHost+": "+Data); // alternative 
char* MSG = new char[ Data.Length() + 1]; 
strcpy( MSG, Data.c_str() ); 
Display(MSG, strlen(MSG)); 
delete MSG; 

MemoText->Lines->Add(""); 
MemoText->Lines->Add("Recu :"); 
MemoText->Lines->Add(Data); 



void __fastcall TClient::Display(char* pBuffer, int BLength) 

int BytesRead; 
String linebuff; 
String texte; 
String hex; 

/* linebuff type 
/* 00000: 43 56 53 0a 4d 61 6b 65 66 69 6c 65 0a 64 65 66 : CVS.Makefile.def */ 

// pszBuffer = new char[FileLength+1]; 
// construction des lignes converties en hexa décimal 
int i=0; 
while ( i < BLength ) 

texte = ""; 
linebuff = " "; // chaine début de ligne 
//string adrhex="0123456"; // adresse 1er octets de la ligne 
//itoa(i, adrhex, 10); // conversion en char et mise en forme 
String adrhex = IntToStr(i); 
if (i<10) linebuff = linebuff + "00000" + adrhex; 
else { 
if (i<100) linebuff = linebuff + "0000" + adrhex; 
else { 
if (i<1000) linebuff = linebuff + "000" + adrhex; 
else { 
if (i<10000) linebuff = linebuff + "00" + adrhex; 
else { 
if (i<100000) linebuff = linebuff + "0" + adrhex; 
else { linebuff = linebuff + adrhex; } 
} } } } 

linebuff = linebuff + " : "; 

for (int j=0; j < 16 ; ++j) // lignes de 16 caracteres 

hex = IntToHex((int)pBuffer[i],2); // conversion octets en hexa 
linebuff = linebuff + " " + hex; 
// transfert du texte 
if ( (pBuffer[i] & 0x80) == 0 && isprint(pBuffer[i]) ) 
texte= texte+ pBuffer[i]; // texte[j]= pszBuffer[i]; 
else texte= texte+ '.'; 
i++; // caractere suivant 

if (i >= BLength) { j=16; } // fin de traitement 


linebuff = linebuff + " : " + texte; // ajout séparation + caracteres 
MemoHex->Lines->Add(linebuff); 



// *********************************


voici la réponse du serveur: 

-------- 
Message Envoyé : 
GET /record/current.jpg HTTP/1.0 
Accept image/jpeg 

Recu : 
HTTP/1.1 200 OK 
Via: 1.1 MYCO-SRV 
Connection: close 
Proxy-Connection: close 
Content-length: 34873 
Date: Fri, 19 Nov 2010 19:17:48 GMT 
Content-type: image/jpeg 
Server: thttpd/2.19-MX Jul 5 2010 
Last-modified: Fri, 19 Nov 2010 19:17:48 GMT 
Accept-Ranges: bytes 

ÿØÿà 
Recu : 
Rm«
ŒS 
üÍë@ïM+ÍNWÐQ.ëëHHù±Þ'€íŠ"®yŠz 
Recu : 
3üî²}ré].Ž?âM¶ô#\ŒMæÙ£÷Àþ=?'®«FçI^ 
..... etc



les donnés hexa correspondantes: 

on retrouve bien les marqueurs jpeg au début : FF D8 FF E0 

J'ai testé le module hexa sur des fichiers exe de plus de 30 Ko. Il fonctionne sans problème à part certains octets qui s'affichent en 32 bits 4 octet exemple FFFFFFD8 au lieu de D8. 
> présentation perturbée 
il faudra que je corrige ce bug! 

000000 : 47 45 54 20 2F 72 65 63 6F 72 64 2F 63 75 72 72 . GET /record/curr 
000016 : 65 6E 74 2E 6A 70 67 20 48 54 54 50 2F 31 2E 30 . ent.jpg HTTP/1.0 
000032 : 0D 0A . .. 
000000 : 41 63 63 65 70 74 20 69 6D 61 67 65 2F 6A 70 65 . Accept image/jpe 
000016 : 67 0D 0A . g.. 
000000 : 0D 0A . .. 
000000 : 48 54 54 50 2F 31 2E 31 20 32 30 30 20 4F 4B 0D . HTTP/1.1 200 OK. 
000016 : 0A 56 69 61 3A 20 31 2E 31 20 4D 59 43 4F 2D 53 . .Via: 1.1 MYCO-S 
000032 : 52 56 0D 0A 43 6F 6E 6E 65 63 74 69 6F 6E 3A 20 . RV..Connection: 
000048 : 63 6C 6F 73 65 0D 0A 50 72 6F 78 79 2D 43 6F 6E . close..Proxy-Con 
000064 : 6E 65 63 74 69 6F 6E 3A 20 63 6C 6F 73 65 0D 0A . nection: close.. 
000080 : 43 6F 6E 74 65 6E 74 2D 6C 65 6E 67 74 68 3A 20 . Content-length: 
000096 : 33 34 38 37 33 0D 0A 44 61 74 65 3A 20 46 72 69 . 34873..Date: Fri 
000112 : 2C 20 31 39 20 4E 6F 76 20 32 30 31 30 20 31 39 . , 19 Nov 2010 19 
000128 : 3A 31 37 3A 34 38 20 47 4D 54 0D 0A 43 6F 6E 74 . :17:48 GMT..Cont 
000144 : 65 6E 74 2D 74 79 70 65 3A 20 69 6D 61 67 65 2F . ent-type: image/ 
000160 : 6A 70 65 67 0D 0A 53 65 72 76 65 72 3A 20 74 68 . jpeg..Server: th 
000176 : 74 74 70 64 2F 32 2E 31 39 2D 4D 58 20 4A 75 6C . ttpd/2.19-MX Jul 
000192 : 20 20 35 20 32 30 31 30 0D 0A 4C 61 73 74 2D 6D . 5 2010..Last-m 
000208 : 6F 64 69 66 69 65 64 3A 20 46 72 69 2C 20 31 39 . odified: Fri, 19 
000224 : 20 4E 6F 76 20 32 30 31 30 20 31 39 3A 31 37 3A . Nov 2010 19:17: 
000240 : 34 38 20 47 4D 54 0D 0A 41 63 63 65 70 74 2D 52 . 48 GMT..Accept-R 
000256 : 61 6E 67 65 73 3A 20 62 79 74 65 73 0D 0A 0D 0A . anges: bytes.... 
000272 : FFFFFFFF FFFFFFD8 FFFFFFFF FFFFFFE0 . .... 
000000 : 52 6D FFFFFFAB 0C FFFFFFBC 53 0A FFFFFFFC FFFFFFCD FFFFFFEB 40 10 14 FFFFFFEF 4D 2B . Rm...S....@...M+ 
000016 : FFFFFFCD 4E 57 07 FFFFFFD0 01 51 FFFFFF95 FFFFFFEB FFFFFFEB 48 08 48 FFFFFFF9 FFFFFFB1 FFFFFFDE . .NW...Q...H.H... 
000032 : FFFFFF91 FFFFFF80 FFFFFFED FFFFFF8A FFFFFF94 FFFFFFAE 79 FFFFFFA6 FFFFFF8F 7A . ......y..z 
000000 : 1B 33 FFFFFFFC FFFFFFEE FFFFFFB2 7F 7D 72 7F 03 FFFFFF8F FFFFFFE9 5D 2E FFFFFF8E 3F . .3....}r....]..? 
000016 : FFFFFFE2 4D 0F FFFFFFB6 7F FFFFFFF4 23 5C FFFFFFBC 4D FFFFFFE6 FFFFFFD9 FFFFFFA3 FFFFFFF7 0E FFFFFFC0 . .M....#\.M...... 
000032 : FFFFFFFE 3D 3F FFFFFF91 FFFFFFAE FFFFFFAB 46 FFFFFFE7 49 FFFFFF88 7B 37 FFFFFFFE FFFFFF84 69 75 . .=?...F.I.{7..iu 
000048 : 1F 42 72 2B FFFFFF9C FFFFFFF1 17 FFFFFF83 6D FFFFFFB5 FFFFFFA6 6B FFFFFF9B 76 16 FFFFFFD7 . .Br+....m..k.v.. 
000064 : FFFFFFBF FFFFFFDF 03 FFFFFFE5 FFFFFF93 FFFFFFFD FFFFFFE1 FFFFFFFD 7F FFFFFF9D 75 02 32 79 FFFFFFC1 FFFFFFA5 . ..........u.2y.. 
000080 : 28 14 1C FFFFFF95 FFFFFFFE 74 58 0F 15 FFFFFFD4 FFFFFFF4 2D 47 48 FFFFFF90 FFFFFF8B . (....tX....-GH.. 
000096 : FFFFFFDB 56 45 FFFFFFCE 04 FFFFFF8A 32 FFFFFF87 FFFFFFE8 47 FFFFFFF5 FFFFFFE6 FFFFFFAA 22 FFFFFF9E FFFFFFFC . .VE...2..G...".. 
000112 : 57 FFFFFFB5 FFFFFFC9 33 0C FFFFFFAE FFFFFFC6 70 78 23 1C 1A FFFFFFC7 FFFFFFB9 FFFFFFD0 FFFFFFF4 . W..3...px#...... 
000128 : FFFFFFCB FFFFFFA6 FFFFFFCB FFFFFFE8 FFFFFFD6 FFFFFFCA FFFFFFC7 FFFFFFF8 FFFFFF90 14 3F FFFFFFF8 FFFFFFE9 14 FFFFFFAC 2B . ..........?....+ 
000144 : 1E 6B 0A FFFFFF82 40 39 3E FFFFFFC0 56 FFFFFFAD FFFFFFA2 FFFFFFEC 23 76 FFFFFFD4 1E . .k..@9>.V...#v.. 
000160 : FFFFFFAE 6B FFFFFFAE 1E 16 FFFFFFD3 3F FFFFFFE7 FFFFFFCA 4C 7A 09 FFFFFF9C 0F FFFFFFE7 5A . .k....?..Lz....Z 
000176 : 16 7A 45 FFFFFF85 FFFFFF9B 06 FFFFFF83 4C FFFFFF85 58 74 66 5D FFFFFFEC 3F 13 . .zE....L.Xtf].?. 
000192 : FFFFFF93 47 29 0E 17 32 FFFFFFB4 2B 07 FFFFFFB8 FFFFFF91 65 FFFFFFDB 24 FFFFFF8B FFFFFFC7 . .G)..2.+...e.$.. 
000208 : 38 FFFFFFDB 1F 1D 31 FFFFFFEA 79 FFFFFFEB FFFFFFC9 FFFFFFAE FFFFFFC2 18 FFFFFF84 23 FFFFFFE4 FFFFFF8C . 8...1.y......#.. 
000224 : 6E FFFFFFEE FFFFFFCD FFFFFFCD 10 33 37 FFFFFFDE 5C 54 FFFFFFFD 28 4A FFFFFFC2 FFFFFF8D 28 . n....37.\T.(J..( 
000240 : FFFFFFC5 FFFFFFDC 6E 24 6E FFFFFFAE 40 FFFFFFF4 1C 52 FFFFFF88 FFFFFF94 73 FFFFFFC1 3E FFFFFFA7 . ..n$n.@..R..s.>. 
000256 : FFFFFF9A 75 15 46 FFFFFFA1 FFFFFFC5 2E 69 29 FFFFFF92 FFFFFFCC FFFFFF90 FFFFFF8F FFFFFF9D FFFFFFB9 FFFFFFFE . .u.F...i).......
000272 : FFFFFFE8 FFFFFFEB 48 09 2A FFFFFFBC FFFFFFD7 07 77 FFFFFF97 10 25 FFFFFFB3 FFFFFFD4 54 12 . ..H.*...w..%..T. 
000288 : 5E FFFFFFBB 7D FFFFFFCC 20 FFFFFFFD 69 2D FFFFFFE4 FFFFFFD9 FFFFFF96 FFFFFFCF 3D 73 40 22 . ^.}. .i-....=s@" 
000304 : FFFFFFC2 5C FFFFFFB2 . .\.



Marc
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
11
ReceiveLength te renvoie probablement très bien la taille du paquet. Mais comme la jpeg est relativement grande, elle est envoyée en plusieurs paquets. SocketRead est appelé pour chaque paquet. Il faut donc accumuler ce que renvoie socketread dans un buffer.

Pour savoir le nombre d'octets de la jpeg, il faut utiliser Content-length: 34873.

Regarde mon code, tout y est.
Messages postés
5
Date d'inscription
mercredi 22 septembre 2010
Statut
Membre
Dernière intervention
11 janvier 2011

j'en été arrivé à la même conclusion exploiter le Content-length: xxxx
Apparemment il n'y a que 2 paquets qui arrivent et la connexion se ferme automatiquement après le second. (voir ci-dessus : voici la réponse du serveur)

j'ai pu tester ton code en delphi 6
il a parfaitement fonctionné du 1er coup

Je tente de l'adapter a C++ Builder 6.
Il y a des fonctions qui ne fonctionnent pas bien pour le traitement des chaines string.
mais je suis proche du but, en fin je pense.

je ne sais pas si ça vient de ma version ou des différences entre pascal / c++ et delphi / builder
par exemple il ne connait pas Pos().
et je ne suis pas certain que dans la commande
socMain.Socket.SendText('GET http://www..... HTTP/1.0' + sLineBreak + sLineBreak);
le GET soit compris ...
j'en saurais plus dès que l'adaptation du code sera terminée.

Marc
Messages postés
5
Date d'inscription
mercredi 22 septembre 2010
Statut
Membre
Dernière intervention
11 janvier 2011

Hello rt15

Mon problème est résolu depuis fin Novembre.
Les indications trouvée dans ton source m'ont bien aidées pour la mise au point de mon programme C++Builder6.

le point le plus délicat à été la réception des paquets d'octets car je pense que certain se perdaient à la réception, notamment à cause de l'affichage Hexa des octets reçus qui devait être trop long.
j'ai donc séparé les problèmes:
1- ouverture du socket
2- traitement de l'évènement OnRead du socket pour l'accumulation des paquets dans un composant Stream
3- Traitement du Stream à la déconnexion du serveur distant : affichage du Header dans un Tmemo et du jpeg dans un TImage.

voici l'adresse du code C++Builder 6 de la solution:

http://www.cppfrance.com/codes/LIRE-IMAGE-JPEG-DEPUIS-ADRESSE-IP_52719.aspx

Merci beaucoup pour l'aide

Marc