Здравствуйте, Hare76, Вы писали:
H>Код примерно такой (убрал все проверки на ошибки, закрытия функций и т.п.)
Похоже, ошибка вот в этом месте:
for(DWORD i=0; i<dwBuffer; i=i+SystemInfo.dwPageSize)
{
bIReadFile=InternetReadFile(hRequest, Buffer, SystemInfo.dwPageSize, &dwNumberOfBytesRead);
BOOL bWriteFile=WriteFileEx(hFile, Buffer,dwNumberOfBytesRead, &ovl, NULL);
ovl.Offset+=dwNumberOfBytesRead;
}
return 0;
}
Суть вот в чем — пока выполняется асинхронная операция ввода-вывода (WriteFileEx в данном случае),
структуру OVERLAPPED нельзя трогать.
MSDN:
The OVERLAPPED data structure must remain valid for the duration of the write operation. It should not be a variable that can go out of scope while the write operation is pending completion.
Здесь же она используется в последующих итерациях цикла,
что является известной ошибкой. Выход такой — либо дождаться завершения WriteFileEx, либо
использовать синхронный ввод-вывод.
Необходимо скачать файл из интернета... достаточно большой (от нескольких десятков мегабайт и выше) по HTTP протоколу. Проблема в том, что если его сразу в буфер целиком закачивать, то все проходит гладко. Но мне надо его закачивать частями, так как не факт, что буфер достаточно большого размера будет выделен на другой машине. Так вот частями он закачивается, только если перед обращениями к InternetReadFile поставить небольшую паузу на треть секунды (или в дебагере пошагово тоже работает). А в реальном времени вылетает с ошибкой сегментации (Access violation). В чем может быть проблема? Может кто сталкивался?
Здравствуйте, okman, Вы писали:
O>Здравствуйте, Hare76, Вы писали:
H>>Необходимо скачать файл из интернета... достаточно большой (от нескольких десятков мегабайт и выше) по HTTP протоколу. Проблема в том, что если его сразу в буфер целиком закачивать, то все проходит гладко. Но мне надо его закачивать частями, так как не факт, что буфер достаточно большого размера будет выделен на другой машине. Так вот частями он закачивается, только если перед обращениями к InternetReadFile поставить небольшую паузу на треть секунды (или в дебагере пошагово тоже работает). А в реальном времени вылетает с ошибкой сегментации (Access violation). В чем может быть проблема? Может кто сталкивался?
O>Покажите код, там будет видно.
O>Скорее всего, неправильно используются функции WinInet.
Код примерно такой (убрал все проверки на ошибки, закрытия функций и т.п.)
#include <windows.h>
#include <wininet.h>
#pragma comment (lib, "wininet.lib")
int main(void)
{
char* lpszAgent = "wini";
HINTERNET hInternet;
hInternet = InternetOpen((LPCWSTR)lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET hConnect;
hConnect=InternetConnect(hInternet, TEXT("obod.by"), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
HINTERNET hRequest;
hRequest = HttpOpenRequest (hConnect, TEXT("GET"), TEXT("images\/shot_049.jpg"), NULL, NULL, 0, INTERNET_FLAG_PRAGMA_NOCACHE|INTERNET_FLAG_RELOAD,1);
BOOL bSend=HttpSendRequest(hRequest, NULL, 0, NULL, 0);
DWORD dwBuffer=0;
DWORD dwBufferLength=4;
BOOL bInfo= HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, &dwBuffer, &dwBufferLength, NULL);
ULARGE_INTEGER FreeBytesAvailable;
ULARGE_INTEGER TotalNumberOfBytes;
ULARGE_INTEGER TotalNumberOfFreeBytes;
BOOL bFreeSpace = GetDiskFreeSpaceEx(NULL, &FreeBytesAvailable, &TotalNumberOfBytes, &TotalNumberOfFreeBytes);
HANDLE hFile;
hFile=CreateFile(TEXT("FileName.jpg"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED/*|FILE_FLAG_NO_BUFFERING*/, NULL);
OVERLAPPED ovl;
ovl.hEvent=NULL;
ovl.Internal=0;
ovl.InternalHigh=0;
ovl.Offset=0;
ovl.OffsetHigh=0;
ovl.Pointer=NULL;
SYSTEM_INFO SystemInfo;
GetSystemInfo(&SystemInfo);
HANDLE hHeap=HeapCreate(0, 0,0);
LPVOID Buffer=HeapAlloc(hHeap, HEAP_ZERO_MEMORY, SystemInfo.dwPageSize);
DWORD dwAllReadBytes=0;
DWORD dwNumberOfBytesRead=0;
BOOL bIReadFile=1;
for(DWORD i=0; i<dwBuffer; i=i+SystemInfo.dwPageSize)
{
bIReadFile=InternetReadFile(hRequest, Buffer, SystemInfo.dwPageSize, &dwNumberOfBytesRead);
BOOL bWriteFile=WriteFileEx(hFile, Buffer,dwNumberOfBytesRead, &ovl, NULL);
ovl.Offset+=dwNumberOfBytesRead;
}
return 0;
}
Здравствуйте, okman, Вы писали:
O>Здравствуйте, Hare76, Вы писали:
H>>Код примерно такой (убрал все проверки на ошибки, закрытия функций и т.п.)
O>Похоже, ошибка вот в этом месте:
O>
O> for(DWORD i=0; i<dwBuffer; i=i+SystemInfo.dwPageSize)
O> {
O> bIReadFile=InternetReadFile(hRequest, Buffer, SystemInfo.dwPageSize, &dwNumberOfBytesRead);
O> BOOL bWriteFile=WriteFileEx(hFile, Buffer,dwNumberOfBytesRead, &ovl, NULL);
O> ovl.Offset+=dwNumberOfBytesRead;
O> }
O> return 0;
O>}
O>
O>Суть вот в чем — пока выполняется асинхронная операция ввода-вывода (WriteFileEx в данном случае),
O>структуру OVERLAPPED нельзя трогать.
O>MSDN:O>The OVERLAPPED data structure must remain valid for the duration of the write operation. It should not be a variable that can go out of scope while the write operation is pending completion.
O>Здесь же она используется в последующих итерациях цикла,
O>что является известной ошибкой. Выход такой — либо дождаться завершения WriteFileEx, либо
O>использовать синхронный ввод-вывод.
Спасибо! Помогло! Как-то даже не подумал...
С меня плюсики