Forum Programmation.c++ Lire un fichier web en C++ avec wxWidgets

Posté par  (site web personnel) .
Étiquettes : aucune
0
4
oct.
2004
Bonjour,
J'ai écrit une fonction en C++ avec wxWidgets pour récupérer une page Web. Mon problème, c'est que la lecture d'un ensemble de fichiers est fortement ralentie par des serveurs down ou très lents / surchargés. La fonction passe alors son temps à attendre. Je souhaiterai donc pouvoir mettre un time out à la lecture du fichier ou à défaut ajouter une fonction préalable qui teste l'accessibilité de la page à récupérer.
Par contre je ne vois pas du tout comment faire.
Quelqu'un peut-il m'éclairer ?
Merci d'avance pour les idées : le code source actuel est en dessous.
RV.


bool readflux (wxString filename, wxString *filecontent)
{
wxInputStream *in_stream = NULL;
int ReadMode = 1;

// DEBUT LECTURE DU FICHIER DISTANT
filename = wxURL::ConvertToValidURI( filename );
wxURL url(filename);

if ( url.GetError() != wxURL_NOERR )
{
// erreur : problème lors de l'analyse de l'URL
return false;
}

wxChar *data = NULL;
size_t size = 0;

try
{
// essai pour ouvrir le flux
in_stream = url.GetInputStream();
}
catch (...)
{
// erreur : problème à l'ouverture du flux RSS.
return false;
}

//////////////////////////////////////////////////
if ( in_stream )
{
// le fichier distant a pu être ouvert
try
{
size = in_stream->StreamSize();
}
catch (...)
{
// erreur : la demande de la taille du fichier a causé une erreur.
ReadMode = 2;
}
}
else
{
// le fichier distant n'a pas pu être ouvert
return false;
}
//////////////////////////////////////////////////

//////////////////////////////////////////////////
// certains fichiers http renvoient leur taille => on passe par Read
// d'autres renvoient -1 => on passe par GetC (ce est plus lent)
if ((int)size > 0)
ReadMode = 1;
else
ReadMode = 2;
//////////////////////////////////////////////////

//////////////////////////////////////////////////
wxString temp;
if (ReadMode==1)
{
if (size > 0)
try
{
data = new wxChar[size];
}
catch (...)
{
// erreur : la création du conteneur a échoué
return false;
}
else
{
// le fichier est de taille nulle ou indéterminée.
return false;
}

try
{
// essai de lire dans le flux
if (!in_stream->Read(data, size))
{
// la lecture du fichier distant a échoué
if (in_stream) delete in_stream;
if (data) delete data;
return false;
}
else
{
wxString _data (data, size);
temp = _data;
// la lecture du fichier distant a réussi
}
}
catch (...)
{
if (in_stream) delete in_stream;
if (data) delete data;
return false;
}
}
else
{
try
{
char c; size = 0;
do
{
c=in_stream->GetC();
size++;
temp.Append (c);
}
while (in_stream->LastRead()>0);
}
catch (...)
{
// erreur a la lecture du fichier caractere par caractere
if (in_stream) delete in_stream;
if (data) delete data;
return false;
}
}

// liberation memoire
if (in_stream) delete in_stream;
if (data) delete data;
// FIN LECTURE FICHIER DISTANT
*filecontent = temp;
return true;
}


Cordialement.
  • # Select

    Posté par  . Évalué à 0.

    man select
    • [^] # Re: Select

      Posté par  (site web personnel) . Évalué à 2.

      Merci. Je me doute bien qu'il y a une histoire de socket par derrière mais j'aurais plus besoin de la méthode à suivre que du nom d'une fonction en particulier :-). Coté doc, je suis servi (celle de wxWidgets est assez complète mais plutôt abstraite : peu d'exemples).
  • # wxURL, wxProtocol, wxSocketBase

    Posté par  (site web personnel) . Évalué à 3.

    Via ton wxURL, tu peut choper un wxProtocol via wxURL::GetProtocol.
    Ensuite, tu peuq remarquer que les wxProtocol dérivent de wxSocketBase (via wxSocketClient). Or dans wxSocketBase, tu peux spécifier les timeouts via
    wxSocketBase::SetTimeout.
    Et au pire, tu peux modifier les flags d'attente via wxSocketBase::SetFlags.

    Socket bien :).

    Un jour libre ?

    • [^] # Re: wxURL, wxProtocol, wxSocketBase

      Posté par  (site web personnel) . Évalué à 1.

      C'est en gros ce que je viens d'essayer.


      // test de connexion
      wxIPV4address addr;
      if (addr.Hostname (filename))
      {
      //addr.Service(80);
      wxSocketClient sock;
      sock.Connect(addr, false);
      sock.WaitOnConnect(10);
      if (!sock.IsConnected())
      textmsg->AppendText ("> La connexion a échoué !\n");
      else
      sock.Close();
      }
      else
      textmsg->AppendText ("> La résolution d'adresse a échoué !\n");


      Mais addr.Hostname (filename) ne marche pas pour l'instant. Il faut que je regarde plus attentivement.

      Ceci étant dit, je recherche en fait quelque chose de plus haut niveau (c'est pour ça que j'ai utilisé wxWidgets pour commencer), genre composant Indy (Open Source mais apparamment lié aux composants Borland). En gros, je cherche un composant capable de télécharger un fichier (style IdHTTP), sans devoir réimplémenter l'ensemble, sans la programmation assez bas niveau des sockets.
  • # Liste de crawlers

    Posté par  (site web personnel) . Évalué à 1.

    Je remercie tout le monde pour les remarques et suggestions.

    Je viens de trouver ceci, qui a l'air intéressant, pour tous ceux qui ont le même problème que moi : http://www.searchtools.com/robots/robot-code.html(...) . Ca liste tout une série de crawlers, parfois minimalistes (mais donc rapidement compréhensibles et personnalisables).

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.