เกี่ยวข้องกับโพสต์ของฉัน ( วิธีดึงไฟล์จากอินเทอร์เน็ต ผ่าน 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.
}
แก้ไข: ฉันตัดการเชื่อมต่ออินเทอร์เน็ตโดยการถอดสายเคเบิลหรือ (สำหรับไร้สาย) ออกจากซอฟต์แวร์หลังจากแอปพลิเคชันเริ่มการดาวน์โหลด (ฉันเลือกดาวน์โหลดไฟล์ขนาดใหญ่) มันจำลองเว็บไซต์ออฟไลน์