Discussion:
wininet Async http downloading size is not stable
(too old to reply)
Flaxie
2007-06-12 11:40:00 UTC
Permalink
I have tried to get wininet http downloading to get right, but somehow I have
failed now. I get different sizes of file all a time with large files.

Here is my test code for command line program (it's taken from example of
wininet, poor coding because of all goto's and everything but still, I am
quite sure it should work)
http://msdn2.microsoft.com/en-US/library/aa383931.aspx


#include "stdafx.h"
#include <windows.h>
#include <wininet.h>
#include <conio.h>
#include <iostream>


#pragma comment(lib, "Wininet.lib")

HINTERNET hOpen;
HINTERNET hRequest;

struct SStored
{
CHAR *data;
DWORD size;
};

//instance of the callback function
INTERNET_STATUS_CALLBACK iscCallback;

//structure to be passed as the dwContext value
typedef struct {
HWND hWindow; //main window handle
int nURL; //ID of the Edit Box w/ the URL
int nHeader; //ID of the Edit Box for the header info
int nResource; //ID of the Edit Box for the resource
HINTERNET hOpen; //HINTERNET handle created by InternetOpen
HINTERNET hResource; //HINTERNET handle created by InternetOpenUrl
char szMemo[512];//string to store status memo
HANDLE hThread; //thread handle
DWORD dwThreadID; //thread ID
} REQUEST_CONTEXT;

int WINAPI Dump( HINTERNET hResource);


SStored StoredData; // data that is received by download
DWORD currentSize;

void __stdcall Juggler (HINTERNET hInternet, DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength)
{
REQUEST_CONTEXT *cpContext;
char szBuffer[512];
cpContext= (REQUEST_CONTEXT*)dwContext;

CHAR *buffer;
DWORD dwRead, dwFlags, dwStatus, dwSize=255 ;
switch (dwInternetStatus)
{
case INTERNET_STATUS_CLOSING_CONNECTION:
printf("closing the connection\n");
//write the callback information to the buffer
break;
case INTERNET_STATUS_CONNECTED_TO_SERVER:
printf("connected to server\n");
//write the callback information to the buffer
break;
case INTERNET_STATUS_CONNECTING_TO_SERVER:
printf("connected to server\n");
//write the callback information to the buffer
break;
case INTERNET_STATUS_CONNECTION_CLOSED:
printf("closed the connection\n");
//write the callback information to the buffer
break;
case INTERNET_STATUS_HANDLE_CLOSING:
//write the callback information to the buffer
printf("handle closing\n");

break;
case INTERNET_STATUS_HANDLE_CREATED:
//write the callback information to the buffer
printf("handle created\n");
break;
case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
//write the callback information to the buffer
printf("INTERNET_STATUS_INTERMEDIATE_RESPONSE\n");
break;
case INTERNET_STATUS_NAME_RESOLVED:
printf("INTERNET_STATUS_NAME_RESOLVED\n");
//write the callback information to the buffer
break;
case INTERNET_STATUS_RECEIVING_RESPONSE:
printf("INTERNET_STATUS_RECEIVING_RESPONSE\n");
//write the callback information to the buffer
break;
case INTERNET_STATUS_RESPONSE_RECEIVED:
printf("INTERNET_STATUS_RESPONSE_RECEIVED\n");
//write the callback information to the buffer
break;
case INTERNET_STATUS_REDIRECT:
printf("INTERNET_STATUS_REDIRECT\n");
//write the callback information to the buffer
break;
case INTERNET_STATUS_REQUEST_COMPLETE:

if (LPINTERNET_ASYNC_RESULT(lpvStatusInformation)->dwError == 0)
{
Dump(hInternet);
}
else
{
}
break;
case INTERNET_STATUS_REQUEST_SENT:
printf("INTERNET_STATUS_REQUEST_SENT\n");
//write the callback information to the buffer
break;
case INTERNET_STATUS_RESOLVING_NAME:
printf("INTERNET_STATUS_RESOLVING_NAME\n");
//write the callback information to the buffer
break;
case INTERNET_STATUS_SENDING_REQUEST:
//write the callback information to the buffer
printf("%s\n", "INTERNET_STATUS_SENDING_REQUEST");
break;
case INTERNET_STATUS_STATE_CHANGE:
printf("INTERNET_STATUS_STATE_CHANGE\n");
//write the callback information to the buffer
break;
default:
//write the callback information to the buffer
printf("WTF");
break;
}

//add the callback information to the callback list box

}
int WINAPI Dump( HINTERNET hResource)
{

LPSTR lpszData; // buffer for the data
DWORD dwSize; // size of the data available
DWORD dwDownloaded; // size of the downloaded data
DWORD dwSizeSum=0; // size of the data in the textbox
LPSTR lpszHolding; // buffer to merge the textbox data and buffer

char szError[80]; // buffer for error information

int nCounter; // counter used to display something while
// I/O is pending.

DWORD new_size;


// This loop handles reading the data.
do
{
// The call to InternetQueryDataAvailable determines the amount of
// data available to download.
if (!InternetQueryDataAvailable(hResource,&dwSize,0,0))
{
if (GetLastError()== ERROR_IO_PENDING)
{
nCounter = 0;

while(GetLastError()==ERROR_IO_PENDING)
{
nCounter++;
if (nCounter==2000)
break;
InternetQueryDataAvailable(hResource,&dwSize,0,0);
}
}
else
{
break;
}
}
else
{
// Allocates a buffer of the size returned by InternetQueryDataAvailable
lpszData = new char[dwSize+1];

// Reads the data from the HINTERNET handle.
if(!InternetReadFile(hResource,(LPVOID)lpszData,dwSize,&dwDownloaded))
{
if (GetLastError()== ERROR_IO_PENDING)
{
nCounter = 0;

while(GetLastError()==ERROR_IO_PENDING)
{
nCounter++;
}
MessageBox(NULL, "dspo", "ds", MB_OK);
goto keep_going;
}
delete[] lpszData;
break;
}
else
{

keep_going:
// Adds a null terminator to the end of the data buffer
lpszData[dwDownloaded]='\0';



new_size = StoredData.size + dwDownloaded;
StoredData.data = (CHAR *)realloc(StoredData.data,
new_size*sizeof(CHAR));
memcpy(StoredData.data+StoredData.size, lpszData,
sizeof(CHAR)*dwDownloaded);
StoredData.size = new_size;

printf("%s", lpszData);
currentSize += dwDownloaded;

printf("Size: %d", currentSize);

if (dwDownloaded == 0)
break;
}
}
}
while(1);

// Close the HINTERNET handle
InternetCloseHandle(hResource);

FILE *f = fopen("d:\\ds.txt", "w+");
fwrite(StoredData.data, 1, StoredData.size, f);
fclose(f);


return TRUE;
}



int _tmain(int argc, _TCHAR* argv[])
{
CHAR buffer[2048] ;
DWORD dwRead, dwFlags, dwStatus ;
// static TCHAR hdrs[] = __TEXT("Content-Type: application/octet-stream");
static TCHAR frmdata[] = __TEXT("name=Tester=hithere&other=P%26Q");

static TCHAR hdrs[] =
_T("Content-Type: application/x-www-form-urlencoded");
// static TCHAR frmdata[] =
// _T("name=John+Doe&userid=hithere&other=P%26Q");
static LPSTR accept[2]={"*/*", NULL};
DWORD dwSize = 2550;
LPVOID lpOutBuffer = NULL;
char lpBuf[2550];
StoredData.size = 0;

hOpen = InternetOpen("test", INTERNET_OPEN_TYPE_PRECONFIG,
NULL, NULL, INTERNET_FLAG_ASYNC);

if (hOpen != NULL)
{
iscCallback = InternetSetStatusCallback(hOpen,
(INTERNET_STATUS_CALLBACK)Juggler);


HINTERNET hConnect = InternetConnect(hOpen,
_T("www.warofenlightenment.com"),
INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);


hRequest = HttpOpenRequest(hConnect, "GET", _T("woeinstall.exe"), NULL,
NULL, NULL, 0, 1);
HttpSendRequest(hRequest, hdrs, strlen(hdrs), frmdata, strlen(frmdata));

while (1)
{
if (kbhit())
{
break;
}
Sleep(10);
}

InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hOpen);
}



MessageBox(NULL, "end", "end", MB_OK);


return 0;
}
Flaxie
2007-06-13 08:38:01 UTC
Permalink
My problem is solved now. I did do this by different way than the example and
now it works.

Loading...