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 »-(¯`v´¯)-» . Évalué à 0.
[^] # Re: Select
Posté par Robert VISEUR (site web personnel) . Évalué à 2.
# wxURL, wxProtocol, wxSocketBase
Posté par Émilien Kia (site web personnel) . Évalué à 3.
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 Robert VISEUR (site web personnel) . Évalué à 1.
// 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.
[^] # Re: wxURL, wxProtocol, wxSocketBase
Posté par -=[ silmaril ]=- (site web personnel) . Évalué à 2.
Peut etre y a t'il un binding C++ ?
Sinon je chercherai du coté de CommonC++ et/ou Boost.
Qui on surement qque chose dans le genre.
# Liste de crawlers
Posté par Robert VISEUR (site web personnel) . Évalué à 1.
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.