Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Не пашет закачка при помощи wininet (проект DLL)

49K
08 декабря 2010 года
S0mbre
16 / / 15.10.2009
Добрый день!

Создал DLL (C++ Builder 2010) для закачки файлов при помощи библиотеки wininet.lib. В DLL 2 экспортируемые функции: для запуска закачки и для ее остановки. Функция закачки имеет в качестве одного из параметров callback функцию для симуляции обработчика событий закачки.
При запуске тестового проекта, использующего эту мою DLL, все вроде бы нормально: подключение к сети, создание файла на диске, начало загрузки... В конце сообщение радостно сообщает, что файл загружен. Однако смотрю на диске и вижу: создан файл нулевого размера, в него ничего не записано. Кроме того, DLL неправильно определяет размер файла по URL-ссылке (каждый раз определяет по-разному). Другими словами, проблема либо в функциях wininet, либо при записи в файл (FileWrite). Не могу определить и решить проблему. Дайте совет / мысль! :)

Прикладываю проекты: [COLOR="Red"]удалены. Отладка и проверка собственных проектов - это первая обязанность программиста.[/COLOR]
1
08 декабря 2010 года
kot_
7.3K / / 20.01.2000
Цитата: S0mbre
Добрый день!

Создал DLL (C++ Builder 2010) для закачки файлов при помощи библиотеки wininet.lib. В DLL 2 экспортируемые функции: для запуска закачки и для ее остановки. Функция закачки имеет в качестве одного из параметров callback функцию для симуляции обработчика событий закачки.
При запуске тестового проекта, использующего эту мою DLL, все вроде бы нормально: подключение к сети, создание файла на диске, начало загрузки... В конце сообщение радостно сообщает, что файл загружен. Однако смотрю на диске и вижу: создан файл нулевого размера, в него ничего не записано. Кроме того, DLL неправильно определяет размер файла по URL-ссылке (каждый раз определяет по-разному). Другими словами, проблема либо в функциях wininet, либо при записи в файл (FileWrite). Не могу определить и решить проблему. Дайте совет / мысль! :)



дебагер рулит. Єто первое. Второе - пример работы с виннет есть в ЧАВО. Ссылки на проекты удалил - ибо нех. отладка и проверка собственных проектов - это целиком и полностью твоя задача.

49K
08 декабря 2010 года
S0mbre
16 / / 15.10.2009
Спасибо! Почитал ФАК, проект переделал и все заработало! Единственно, ф-ция InternetQueryDataAvailable из wininet неверно возвращает размер файла, вследствие чего невозможно нормально отображать прогресс загрузки в прогресс-баре. И еще: почему-то докачка при помощи перемещения позиции в FileStream не происходит:
Код:
DWORD ResumePos, BufferLen, SumSize;
...
if (!fs) fs = new TFileStream(UnicodeString(sFilename), fmCreate);
ResumePos = fs->Seek((__int64)0, soEnd); // Откуда докачать
...
hURL = InternetOpenUrl(hSession, sURL, NULL, 0, INTERNET_FLAG_KEEP_CONNECTION, 0);
if (ResumePos>0) InternetSetFilePointer(hURL, ResumePos, NULL, 0, 0); // если докачка
...
char Buffer[1024];
while (goondownload) {
err = InternetReadFile(hURL, (LPVOID)Buffer, 1024, &BufferLen);
...
fs->Write((LPVOID)Buffer, BufferLen); // почему-то не докачивается
}
...
246
09 декабря 2010 года
GIZMO
1.8K / / 30.07.2004
Цитата: S0mbre
Спасибо! Почитал ФАК, проект переделал и все заработало! Единственно, ф-ция InternetQueryDataAvailable из wininet неверно возвращает размер файла


Вообще сервер не всегда возвращает размер файла. Попробуй HttpQueryInfo, там можно получить более развернутую информацию.

49K
15 декабря 2010 года
S0mbre
16 / / 15.10.2009
Цитата: GIZMO
Вообще сервер не всегда возвращает размер файла. Попробуй HttpQueryInfo, там можно получить более развернутую информацию.



Спасибо! Помогло!
Еще вопрос: есть ли где-нибудь полезный пример отправки запросов "GET" с заголовками и получения заголовков с сервера? Примерно как это делает DownloadMaster (при выведении окна лога закачек):

Цитата:

16 15.12.2010 17:49:16 Start new section [1]
17 15.12.2010 17:49:16 Start connection to proxy2.ufa-ntc.rn.ru:3128 [1]
18 15.12.2010 17:49:16 Connecting to proxy2.ufa-ntc.rn.ru:3128 [1]
19 15.12.2010 17:49:16 Connected [1]
20 15.12.2010 17:49:16 GET http://wordexpert.ru/wp-content/uploads/macros/SrcAndRpl_Beta3.zip HTTP/1.0
User-Agent: Download Master
Accept: */*
Referer: http://wordexpert.ru/wp-content/uploads/macros/
Pragma: no-cache
Cache-Control: no-cache
Host: wordexpert.ru
Proxy-Authorization: Basic ********
21 15.12.2010 17:49:16 HTTP/1.0 200 OK
Date: Wed, 15 Dec 2010 12:49:12 GMT
Server: Apache/1.3.37-lk.d (Unix) mod_python/2.7.11 Python/2.4.3 PHP/4.4.4 mod_dp/lk.0.4.4
Last-Modified: Sun, 20 Sep 2009 16:53:02 GMT
ETag: "1d701c8-eb82-4ab65dee"
Accept-Ranges: bytes
Content-Length: 60290
Content-Type: application/zip
X-Cache: MISS from ****
X-Cache-Lookup: MISS from proxy-2.****
Via: 1.1 proxy-2.ufa-ntc.rn.ru:3128 (squid/2.7.STABLE6)
Connection: close
22 15.12.2010 17:49:18 Closing socket [1]
23 15.12.2010 17:49:18 Socket disconnected [1]
24 15.12.2010 17:49:18 Section complete [1]
25 15.12.2010 17:49:18 Download state changed to Downloaded
26 15.12.2010 17:49:18 DOWNLOAD FILE COMPLETE: C:\Downloads\Архивы\SrcAndRpl_Beta3.zip
27 15.12.2010 17:49:18 Start delete section [1]
28 15.12.2010 17:49:18 Section deleted [1]
29 15.12.2010 17:49:18 Destination file already exists
30 15.12.2010 17:49:18 Use auto rename. Rename to SrcAndRpl_Beta3[1].zip
31 15.12.2010 17:49:18 Downloaded file moved to C:\Downloads\Архивы\SrcAndRpl_Beta3[1].zip

1
15 декабря 2010 года
kot_
7.3K / / 20.01.2000
не забывайте самостоятельно удалять конфедициальную информацию из приведенных логов.
по поводу вопроса - ключевая фраза для поиска по форуму - "использование сокетов", "сокет", "socket"
49K
16 декабря 2010 года
S0mbre
16 / / 15.10.2009
Спасибо. Подскажите еще пожалуйста, как правильно присоединить заголовки к InternetOpenUrl.

Делаю так:
 
Код:
const char *Headers = "HTTP/1.0";
    // Открыть URL
    hURL_ = InternetOpenUrl(hSession_, sURL, Headers, -1L,
                            INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_PRAGMA_NOCACHE,
                            NULL);
if (!hURL_) {
        Application->MessageBoxA(L"Не могу подсоединиться к URL!", L"Ошибка!", 0);
        if (hSession_) InternetCloseHandle(hSession_);
        return ERR_INET_OPENURL;
    }


И вылезает ошибка. Если не подключать заголовок, т.е.
 
Код:
hURL_ = InternetOpenUrl(hSession_, sURL, NULL, 0,
                            INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_PRAGMA_NOCACHE,
                            NULL);


То тогда все нормально.

Я это делаю с тем, чтобы затем получить с сервера ответ
Цитата:

LPVOID lpOutBuffer=NULL;
DWORD dwSize = 0;

if (!HttpQueryInfo (hURL_, HTTP_QUERY_RAW_HEADERS_CRLF, (LPVOID) lpOutBuffer, &dwSize, NULL)) {
DWORD err = GetLastError();
switch (err) {
case ERROR_HTTP_HEADER_NOT_FOUND:
Application->MessageBoxA(L"Заголовки не найдены!", L"Ошибка!", 0);
if (hURL_) InternetCloseHandle(hURL_);
if (hSession_) InternetCloseHandle(hSession_);
return ERR_NOHEADER;
case ERROR_INSUFFICIENT_BUFFER:
lpOutBuffer = new char[dwSize];
if (!HttpQueryInfo (hURL_, HTTP_QUERY_RAW_HEADERS_CRLF, (LPVOID) lpOutBuffer, &dwSize, NULL)) {
Application->MessageBoxA(L"Ошибка буфера заголовков!", L"Ошибка!", 0);
if (lpOutBuffer) delete [] lpOutBuffer;
if (hURL_) InternetCloseHandle(hURL_);
if (hSession_) InternetCloseHandle(hSession_);
return ERR_BUFFERSIZE;
}
break;
default:
Application->MessageBoxA(L"Ошибка функции 'GetHeaders'!", L"Ошибка!", 0);
if (lpOutBuffer) delete [] lpOutBuffer;
if (hURL_) InternetCloseHandle(hURL_);
if (hSession_) InternetCloseHandle(hSession_);
return ERR_UNKNOWN;
}
}



В связи с этим еще вопрос: если в InternetOpenUrl удастся подключить заголовок о версии протокола (1.0), то будет ли ответ также содержать
"HTTP/1.0" (на данный момент 1.1)?

1
16 декабря 2010 года
kot_
7.3K / / 20.01.2000
используй GetLastError что бы получить внятное сообщение о ошибке.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог