Что касается сообщения моего (How to retrieve a file from Internet via HTTP?) о том, как легко и безопасно загружать файл из Интернета, я нашел возможное решение - однако он не работает так, как предполагалось Работа.Соединение не время ожидания при загрузке файла из интернета
Согласно документации MS, приведенный ниже код рассчитан на тайм-аут через 500 мс после того, как я отключусь от Интернета. Однако похоже, что он полностью игнорирует настройку «INTERNET_OPTION_RECEIVE_TIMEOUT». Приложение зависает во время загрузки. Для этой функции требуется около 20-30, чтобы понять, что подключение к Интернету отключено и вернуть управление GUI.
Никто не знает почему?
function GetBinFileHTTP (const aUrl: string; const pStream: TStream; wTimeOut: Word= 500; wSleep: Word= 500; wAttempts: Word= 10): Integer;
CONST
BufferSize = 1024;
VAR
hSession, hService: HINTERNET;
Buffer : array[0..BufferSize-1] of Char;
dwBytesRead, dwBytesAvail: DWORD;
lSucc : LongBool;
lRetries, dwTimeOut: Integer;
begin
Result:= 0;
if NOT IsConnectedToInternet then
begin
Result:= -1;
EXIT;
end;
hSession := InternetOpen(PChar(ExtractFileName(Application.ExeName)), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); { The INTERNET_OPEN_TYPE_PRECONFIG flag specifies that if the user has configured Internet Explorer to use a proxy server, WinInet will use it as well. }
if NOT Assigned(hSession) then
begin
Result:= -4;
EXIT;
end;
TRY
hService := InternetOpenUrl(hSession, PChar(aUrl), nil, 0, INTERNET_FLAG_RELOAD, 0);
if NOT Assigned(hService) then Exit;
TRY
FillChar(Buffer, SizeOf(Buffer), 0);
{ Set time out }
dwTimeOut:= wTimeOut;
InternetSetOption(hService, INTERNET_OPTION_RECEIVE_TIMEOUT, @dwTimeOut, SizeOf(dwTimeOut)); { use INTERNET_FLAG_RELOAD instead of NIL to redownload the file instead of using the cache }
InternetSetOption(hService, INTERNET_OPTION_CONNECT_TIMEOUT, @dwTimeOut, SizeOf(dwTimeOut));
REPEAT
lRetries := 0;
REPEAT
lSucc:= InternetQueryDataAvailable(hService, dwBytesAvail, 0, 0);
if NOT lSucc
then Sleep(wSleep);
if lRetries > wAttempts
then Result:= -2;
UNTIL lSucc OR (Result= -2);
if NOT InternetReadFile(hService, @Buffer, BufferSize, dwBytesRead) then
begin
Result:= -3; { Error: File not found/File cannot be downloaded }
EXIT;
end;
if dwBytesRead = 0
then Break;
pStream.WriteBuffer(Buffer[0], dwBytesRead);
UNTIL False;
FINALLY
InternetCloseHandle(hService);
end;
FINALLY
InternetCloseHandle(hSession);
end;
Result:= 1;
end;
Вот документация:
{
INTERNET_OPTION_CONNECT_TIMEOUT Sets or retrieves an unsigned long integer value that contains the time-out value to use for Internet connection requests. If a connection request takes longer than this time-out value, the request is canceled. When attempting to connect to multiple IP addresses for a single host (a multihome host), the timeout limit is cumulative for all of the IP addresses. This option can be used on any HINTERNET handle, including a NULL handle. It is used by InternetQueryOption and InternetSetOption.
INTERNET_OPTION_RECEIVE_TIMEOUT Sets or retrieves an unsigned long integer value that contains the time-out value to receive a response to a request. If the response takes longer than this time-out value, the request is canceled. This option can be used on any HINTERNET handle, including a NULL handle. It is used by InternetQueryOption and InternetSetOption. For using WinInet synchronously, only the default value for this flag can be changed by calling InternetSetOption and passing NULL in the hInternet parameter.
INTERNET_OPTION_CONTROL_RECEIVE_TIMEOUT - Identical to INTERNET_OPTION_RECEIVE_TIMEOUT. This is used by InternetQueryOption and InternetSetOption.
}
Edit: я отключаю интернет, отсоединив кабель или (для беспроводных сетей) от программного обеспечения после применения начнет загрузку (я выбрал, чтобы загрузить большой файл). Он имитирует веб-сайт, отправляющийся в автономный режим.
Разве вы не рады, что вы не усложнили ситуацию, просто используя Indy? –
Просто уточнить. Я не говорю, что Indy плохо! Это слишком много для того, что мне нужно. Я хочу, чтобы иметь возможность взять приложение со мной и скомпилировать его на ЛЮБОЙ Delphi включить компьютер. Портативность - это не плохо, не так ли? – Ampere
Чтобы ответить на свой вопрос, нажмите кнопку «ответить на свой вопрос» внизу этой страницы. Затем введите свой ответ так же, как и для любого другого вопроса на сайте. После периода ожидания вы можете пометить его как принятый ответ. –