Embarcadero C++ Builder 2010 を使用して、ネットワークに接続された特定の Web サーバー デバイスを検出しようとしています。
TIdHTTP を使用して CGI 関数を呼び出し、IP アドレスの範囲で回答を分析することで、これらのデバイスに問い合わせています。
IdHTTP->ConnectTimeout および IdHTTP->ReadTimeout パラメーターを使用して、タイムアウトが経過するまでに接続がない場合に例外をスローします。これは、TIdHTTP が予期しないデバイスに問い合わせているときに発生するはずです。この場合、IdHTTP->Free() を呼び出して IdHTTP を解放します。
Windows 7 では問題なく動作しますが、Windows XP ではタイムアウトが適用されないため、IdHTTP.get() が停止するまでに最大 10 分かかる場合があります。
これら 2 つのパラメーターを削除することで、アプリは Windows XP で少し速く動作しますが、タイムアウトに比べて予想よりも時間がかかります。
実際の解決策のないこの関連する件名を見つけました: Indy 10 + SSL = Windows 7 で動作しますが、XP では動作しません
これはソース コードの一部です。
#include "winsock2.h"
String url = "http://" + anIpAddress + "/myCGIFunction.cgi";
TMemoryStream *XML = new TMemoryStream;
AnsiString answer="";
p_IdHTTP = new TIdHTTP(NULL);
try
{
p_IdHTTP->ConnectTimeout = 2000;
p_IdHTTP->Get(url,XML);
XML->Position = 0;
answer=ReadStringFromStream(XML);
p_IdHTTP->Free();
}
catch (...)
{
p_IdHTTP->Free();
}
私の質問は: Windows XP で IdHTTP->ConnectTimeout が機能しないのはなぜですか? そして、このパラメータを特定の時間後に IdHTTP を解放/破棄するように置き換える考えはありますか?
アップデート:
void __fastcall Func::MyFunc()
{
AnsiString anIpAddress= "20.20.20.11";
String url = "http://" + anIpAddress + "/myCGIFunction.cgi";
TMemoryStream *XML = new TMemoryStream;
AnsiString answer="";
p_IdHTTP = new TIdHTTP(NULL);
try
{
p_SSLHandler=new TIdSSLIOHandlerSocketOpenSSL(p_IdHTTP);
p_SSLHandler->SSLOptions->Method= sslvSSLv23;
p_IdHTTP->ConnectTimeout = 2000;
p_IdHTTP->ReadTimeout=400;
p_IdHTTP->IOHandler=p_SSLHandler;
p_IdHTTP->OnConnected= IdHTTPConnected;
p_IdHTTP->OnStatus= IdHTTPStatus;
p_IdHTTP->Get(url,XML);
XML->Position = 0;
answer=ReadStringFromStream(XML);
p_IdHTTP->Free();
}
catch (...)
{
p_IdHTTP->Free();
}
}
void __fastcall Func::IdHTTPStatus(TObject *Sender, TIdStatus const AStatus, String const AStatusText){
String msgtest = ipAddress ;
switch (AStatus){
case (hsResolving):
msgtest+= " resolving...";
break;
case (hsConnecting):
msgtest+= " connecting...";
break;
case (hsConnected):
msgtest+= " connected...";
break;
case (hsDisconnecting):
msgtest+= " disconnecting...";
break;
case (hsDisconnected):
msgtest+= " disconnected...";
break;
case (hsStatusText):
msgtest+= " hsStatusText: " + AStatusText;
break;
default:
msgtest+= " Other status ";
break;
}
aListBox->Items->Add(msgtest);
Application->ProcessMessages();
}
void __fastcall Func::IdHTTPConnected(TObject *Sender){
struct timeval timeout;
timeout.tv_sec = 2;
timeout.tv_usec = 0;
setsockopt((unsigned int) p_IdHTTP->Socket->Binding, SOL_SOCKET,
SO_RCVTIMEO, (char *)&timeout, sizeof(timeout) );
setsockopt ((unsigned int) p_IdHTTP->Socket->Binding, SOL_SOCKET, SO_SNDTIMEO,
(char *)&timeout, sizeof(timeout));
}