全部转自 http://loskill.icode.csdn.net/post/2007/05/31/53930,如下代码所示
在WinInet中使用异步方式
loskill @ 2007-05-31 17:19 | C++
WinInet的异步调用
#include<WINDOWS.H>
#include<WININET.H>
#include<IOSTREAM.H>
HANDLE hConnectedEvent, hRequestOpenedEvent, hRequestCompleteEvent;
HINTERNET hInstance, hConnect, hRequest;
char *lpszUrl, *lpszServer;
BOOL bAllDone = FALSE;
BOOL bVerbose = FALSE;
void __stdcall Callback(HINTERNET hInternet,
DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpStatusInfo,
DWORD dwStatusInfoLen);
void main(int argc, char *argv[])
{
if (argc != 3)
{
if ((argc == 4) && (argv[3][0] == 'v'))
bVerbose = TRUE;
else
{
cout << "Usage: asynchttp <SERVER> <URL> [v]" << endl;
cout << " <SERVER> is the hostname of the http server" << endl;
cout << " <URL> is the url of the object you are requesting (without the hostname)" << endl;
cout << " 'v' for verbose output" << endl << endl;
cout << " Example: asynchttp www.domain.com /docs/readme.htm v" << endl;
return;
}
}
lpszServer = argv[1];
lpszUrl = argv[2];
hConnectedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hRequestOpenedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hRequestCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hInstance = InternetOpen("asynchttp",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
INTERNET_FLAG_ASYNC); // ASYNC Flag
if (hInstance == NULL)
{
cout << "InternetOpen failed, error " << GetLastError();
return;
}
// Setup callback function
if (InternetSetStatusCallback(hInstance,
(INTERNET_STATUS_CALLBACK)&Callback) == INTERNET_INVALID_STATUS_CALLBACK)
{
cout << "InternetSetStatusCallback failed, error " << GetLastError();
return;
}
// First call that will actually complete asynchronously even
// though there is no network traffic
hConnect = InternetConnect(hInstance,
lpszServer,
INTERNET_DEFAULT_HTTP_PORT,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
1); // Connection handle's Context
if (hConnect == NULL)
{
if (GetLastError() != ERROR_IO_PENDING)
{
cout << "InternetConnect failed, error " << GetLastError();
return;
}
// Wait until we get the connection handle
WaitForSingleObject(hConnectedEvent, INFINITE);
}
// Open the request
hRequest = HttpOpenRequest(hConnect,
"GET",
lpszUrl,
NULL,
NULL,
NULL,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE,
2); // Request handle's context
if (hRequest == NULL)
{
if (GetLastError() != ERROR_IO_PENDING)
{
cout << "HttpOpenRequest failed, error " << GetLastError();
return;
}
// Wait until we get the request handle
WaitForSingleObject(hRequestOpenedEvent, INFINITE);
}
if (!HttpSendRequest(hRequest,
NULL,
0,
NULL,
0))
{
if (GetLastError() != ERROR_IO_PENDING)
{
cout << "HttpSendRequest failed, error " << GetLastError();
return;
}
}
if (bVerbose)
{
cout << "HttpSendRequest called successfully" << endl;
cout.flush();
}
WaitForSingleObject(hRequestCompleteEvent, INFINITE);
cout << "------------------- Read the response -------------------" << endl;
char lpReadBuff[256];
do
{
INTERNET_BUFFERS InetBuff;
FillMemory(&InetBuff, sizeof(InetBuff), 0);
InetBuff.dwStructSize = sizeof(InetBuff);
InetBuff.lpvBuffer = lpReadBuff;
InetBuff.dwBufferLength = sizeof(lpReadBuff) - 1;
if (bVerbose)
{
cout << "Calling InternetReadFileEx" << endl;
cout.flush();
}
if (!InternetReadFileEx(hRequest,
&InetBuff,
0, 2))
{
if (GetLastError() == ERROR_IO_PENDING)
{
if (bVerbose)
{
cout << "Waiting for InternetReadFileEx to complete" << endl;
cout.flush();
}
WaitForSingleObject(hRequestCompleteEvent, INFINITE);
}
else
{
cout << "InternetReadFileEx failed, error " << GetLastError();
cout.flush();
return;
}
}
lpReadBuff[InetBuff.dwBufferLength] = 0;
cout << lpReadBuff;
cout.flush();
if (InetBuff.dwBufferLength == 0)
bAllDone = TRUE;
} while (bAllDone == FALSE);
cout << endl << endl << "------------------- Request Complete ----------------" << endl;
}
void __stdcall Callback(HINTERNET hInternet,
DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpStatusInfo,
DWORD dwStatusInfoLen)
{
if (bVerbose)
{
cout << "Callback dwInternetStatus: " << dwInternetStatus << " Context: " << dwContext << endl;
cout.flush();
}
switch(dwContext)
{
case 1: // Connection handle
if (dwInternetStatus == INTERNET_STATUS_HANDLE_CREATED)
{
INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
hConnect = (HINTERNET)pRes->dwResult;
if (bVerbose)
{
cout << "Connect handle created" << endl;
cout.flush();
}
SetEvent(hConnectedEvent);
}
break;
case 2: // Request handle
switch(dwInternetStatus)
{
case INTERNET_STATUS_HANDLE_CREATED:
{
INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
hRequest = (HINTERNET)pRes->dwResult;
if (bVerbose)
{
cout << "Request handle created" << endl;
cout.flush();
}
SetEvent(hRequestOpenedEvent);
}
break;
case INTERNET_STATUS_REQUEST_SENT:
{
DWORD *lpBytesSent = (DWORD*)lpStatusInfo;
if (bVerbose)
{
cout << "Bytes Sent: " << *lpBytesSent << endl;
cout.flush();
}
}
break;
case INTERNET_STATUS_REQUEST_COMPLETE:
{
INTERNET_ASYNC_RESULT *pAsyncRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
if (bVerbose)
{
cout << "Function call finished" << endl;
cout << "dwResult: " << pAsyncRes->dwResult << endl;
cout << "dwError: " << pAsyncRes->dwError << endl;
cout.flush();
}
SetEvent(hRequestCompleteEvent);
}
break;
case INTERNET_STATUS_RECEIVING_RESPONSE:
if (bVerbose)
{
cout << "Receiving Response" << endl;
cout.flush();
}
break;
case INTERNET_STATUS_RESPONSE_RECEIVED:
{
DWORD *dwBytesReceived = (DWORD*)lpStatusInfo;
if (*dwBytesReceived == 0)
bAllDone = TRUE;
if (bVerbose)
{
cout << "Received " << *dwBytesReceived << endl;
cout.flush();
}
}
}
}
}
#include<WININET.H>
#include<IOSTREAM.H>
HANDLE hConnectedEvent, hRequestOpenedEvent, hRequestCompleteEvent;
HINTERNET hInstance, hConnect, hRequest;
char *lpszUrl, *lpszServer;
BOOL bAllDone = FALSE;
BOOL bVerbose = FALSE;
void __stdcall Callback(HINTERNET hInternet,
DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpStatusInfo,
DWORD dwStatusInfoLen);
void main(int argc, char *argv[])
{
if (argc != 3)
{
if ((argc == 4) && (argv[3][0] == 'v'))
bVerbose = TRUE;
else
{
cout << "Usage: asynchttp <SERVER> <URL> [v]" << endl;
cout << " <SERVER> is the hostname of the http server" << endl;
cout << " <URL> is the url of the object you are requesting (without the hostname)" << endl;
cout << " 'v' for verbose output" << endl << endl;
cout << " Example: asynchttp www.domain.com /docs/readme.htm v" << endl;
return;
}
}
lpszServer = argv[1];
lpszUrl = argv[2];
hConnectedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hRequestOpenedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hRequestCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hInstance = InternetOpen("asynchttp",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
INTERNET_FLAG_ASYNC); // ASYNC Flag
if (hInstance == NULL)
{
cout << "InternetOpen failed, error " << GetLastError();
return;
}
// Setup callback function
if (InternetSetStatusCallback(hInstance,
(INTERNET_STATUS_CALLBACK)&Callback) == INTERNET_INVALID_STATUS_CALLBACK)
{
cout << "InternetSetStatusCallback failed, error " << GetLastError();
return;
}
// First call that will actually complete asynchronously even
// though there is no network traffic
hConnect = InternetConnect(hInstance,
lpszServer,
INTERNET_DEFAULT_HTTP_PORT,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
1); // Connection handle's Context
if (hConnect == NULL)
{
if (GetLastError() != ERROR_IO_PENDING)
{
cout << "InternetConnect failed, error " << GetLastError();
return;
}
// Wait until we get the connection handle
WaitForSingleObject(hConnectedEvent, INFINITE);
}
// Open the request
hRequest = HttpOpenRequest(hConnect,
"GET",
lpszUrl,
NULL,
NULL,
NULL,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE,
2); // Request handle's context
if (hRequest == NULL)
{
if (GetLastError() != ERROR_IO_PENDING)
{
cout << "HttpOpenRequest failed, error " << GetLastError();
return;
}
// Wait until we get the request handle
WaitForSingleObject(hRequestOpenedEvent, INFINITE);
}
if (!HttpSendRequest(hRequest,
NULL,
0,
NULL,
0))
{
if (GetLastError() != ERROR_IO_PENDING)
{
cout << "HttpSendRequest failed, error " << GetLastError();
return;
}
}
if (bVerbose)
{
cout << "HttpSendRequest called successfully" << endl;
cout.flush();
}
WaitForSingleObject(hRequestCompleteEvent, INFINITE);
cout << "------------------- Read the response -------------------" << endl;
char lpReadBuff[256];
do
{
INTERNET_BUFFERS InetBuff;
FillMemory(&InetBuff, sizeof(InetBuff), 0);
InetBuff.dwStructSize = sizeof(InetBuff);
InetBuff.lpvBuffer = lpReadBuff;
InetBuff.dwBufferLength = sizeof(lpReadBuff) - 1;
if (bVerbose)
{
cout << "Calling InternetReadFileEx" << endl;
cout.flush();
}
if (!InternetReadFileEx(hRequest,
&InetBuff,
0, 2))
{
if (GetLastError() == ERROR_IO_PENDING)
{
if (bVerbose)
{
cout << "Waiting for InternetReadFileEx to complete" << endl;
cout.flush();
}
WaitForSingleObject(hRequestCompleteEvent, INFINITE);
}
else
{
cout << "InternetReadFileEx failed, error " << GetLastError();
cout.flush();
return;
}
}
lpReadBuff[InetBuff.dwBufferLength] = 0;
cout << lpReadBuff;
cout.flush();
if (InetBuff.dwBufferLength == 0)
bAllDone = TRUE;
} while (bAllDone == FALSE);
cout << endl << endl << "------------------- Request Complete ----------------" << endl;
}
void __stdcall Callback(HINTERNET hInternet,
DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpStatusInfo,
DWORD dwStatusInfoLen)
{
if (bVerbose)
{
cout << "Callback dwInternetStatus: " << dwInternetStatus << " Context: " << dwContext << endl;
cout.flush();
}
switch(dwContext)
{
case 1: // Connection handle
if (dwInternetStatus == INTERNET_STATUS_HANDLE_CREATED)
{
INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
hConnect = (HINTERNET)pRes->dwResult;
if (bVerbose)
{
cout << "Connect handle created" << endl;
cout.flush();
}
SetEvent(hConnectedEvent);
}
break;
case 2: // Request handle
switch(dwInternetStatus)
{
case INTERNET_STATUS_HANDLE_CREATED:
{
INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
hRequest = (HINTERNET)pRes->dwResult;
if (bVerbose)
{
cout << "Request handle created" << endl;
cout.flush();
}
SetEvent(hRequestOpenedEvent);
}
break;
case INTERNET_STATUS_REQUEST_SENT:
{
DWORD *lpBytesSent = (DWORD*)lpStatusInfo;
if (bVerbose)
{
cout << "Bytes Sent: " << *lpBytesSent << endl;
cout.flush();
}
}
break;
case INTERNET_STATUS_REQUEST_COMPLETE:
{
INTERNET_ASYNC_RESULT *pAsyncRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
if (bVerbose)
{
cout << "Function call finished" << endl;
cout << "dwResult: " << pAsyncRes->dwResult << endl;
cout << "dwError: " << pAsyncRes->dwError << endl;
cout.flush();
}
SetEvent(hRequestCompleteEvent);
}
break;
case INTERNET_STATUS_RECEIVING_RESPONSE:
if (bVerbose)
{
cout << "Receiving Response" << endl;
cout.flush();
}
break;
case INTERNET_STATUS_RESPONSE_RECEIVED:
{
DWORD *dwBytesReceived = (DWORD*)lpStatusInfo;
if (*dwBytesReceived == 0)
bAllDone = TRUE;
if (bVerbose)
{
cout << "Received " << *dwBytesReceived << endl;
cout.flush();
}
}
}
}
}
如何通过创建另一个线程控制连接超时值(转自MSDN)
loskill @ 2007-05-31 16:53 | C++
要对设置超值 InternetSetOption API 错误由创建另一个线程此 acticle 显示解决。 有关错误, 请参见下列文章 Microsoft 知识库文章
#include <WINDOWS.H>
#include <WININET.H>
#include <IOSTREAM.H>
DWORD WINAPI WorkerFunction( LPVOID );
HINTERNET g_hOpen, g_hConnect;
typedef struct
{
CHAR* pHost;
CHAR* pUser;
CHAR* pPass;
} PARM;
void main()
{
CHAR szHost[] = "localhost";
CHAR szUser[] = "JoeB";
CHAR szPass[] = "test";
CHAR szLocalFile[] = "localfile";
CHAR szRemoteFile[] = "remotefile";
DWORD dwExitCode;
DWORD dwTimeout;
PARM threadParm;
g_hOpen = 0;
if ( !( g_hOpen = InternetOpen ( "FTP sample",
LOCAL_INTERNET_ACCESS,
NULL,
0,
0 ) ) )
{
cerr << "Error on InternetOpen: " << GetLastError() << endl;
return ;
}
// Create a worker thread
HANDLE hThread;
DWORD dwThreadID;
threadParm.pHost = szHost;
threadParm.pUser = szUser;
threadParm.pPass = szPass;
hThread = CreateThread(
NULL, // Pointer to thread security attributes
0, // Initial thread stack size, in bytes
WorkerFunction, // Pointer to thread function
&threadParm, // The argument for the new thread
0, // Creation flags
&dwThreadID // Pointer to returned thread identifier
);
// Wait for the call to InternetConnect in worker function to complete
dwTimeout = 5000; // in milliseconds
if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT )
{
cout << "Can not connect to server in "
<< dwTimeout << " milliseconds" << endl;
if ( g_hOpen )
InternetCloseHandle ( g_hOpen );
// Wait until the worker thread exits
WaitForSingleObject ( hThread, INFINITE );
cout << "Thread has exited" << endl;
return ;
}
// The state of the specified object (thread) is signaled
dwExitCode = 0;
if ( !GetExitCodeThread( hThread, &dwExitCode ) )
{
cerr << "Error on GetExitCodeThread: " << GetLastError() << endl;
return ;
}
CloseHandle (hThread);
if ( dwExitCode )
// Worker function failed
return ;
if ( !FtpGetFile ( g_hConnect,
szRemoteFile,
szLocalFile,
FALSE,INTERNET_FLAG_RELOAD,
FTP_TRANSFER_TYPE_ASCII,
0 ) )
{
cerr << "Error on FtpGetFile: " << GetLastError() << endl;
return ;
}
if ( g_hConnect )
InternetCloseHandle( g_hConnect );
if ( g_hOpen )
InternetCloseHandle( g_hOpen );
return ;
}
/// WorkerFunction //
DWORD WINAPI
WorkerFunction(
IN LPVOID vThreadParm
)
/*
Purpose:
Call InternetConnect to establish a FTP session
Arguments:
vThreadParm - points to PARM passed to thread
Returns:
returns 0
*/
{
PARM* pThreadParm;
// Initialize local pointer to void pointer passed to thread
pThreadParm = (PARM*)vThreadParm;
g_hConnect = 0;
if ( !( g_hConnect = InternetConnect (
g_hOpen,
pThreadParm->pHost,
INTERNET_INVALID_PORT_NUMBER,
pThreadParm->pUser,
pThreadParm->pPass,
INTERNET_SERVICE_FTP,
0,
0 ) ) )
{
cerr << "Error on InternetConnnect: " << GetLastError() << endl;
return 1; // failure
}
return 0; // success
}
#include <WININET.H>
#include <IOSTREAM.H>
DWORD WINAPI WorkerFunction( LPVOID );
HINTERNET g_hOpen, g_hConnect;
typedef struct
{
CHAR* pHost;
CHAR* pUser;
CHAR* pPass;
} PARM;
void main()
{
CHAR szHost[] = "localhost";
CHAR szUser[] = "JoeB";
CHAR szPass[] = "test";
CHAR szLocalFile[] = "localfile";
CHAR szRemoteFile[] = "remotefile";
DWORD dwExitCode;
DWORD dwTimeout;
PARM threadParm;
g_hOpen = 0;
if ( !( g_hOpen = InternetOpen ( "FTP sample",
LOCAL_INTERNET_ACCESS,
NULL,
0,
0 ) ) )
{
cerr << "Error on InternetOpen: " << GetLastError() << endl;
return ;
}
// Create a worker thread
HANDLE hThread;
DWORD dwThreadID;
threadParm.pHost = szHost;
threadParm.pUser = szUser;
threadParm.pPass = szPass;
hThread = CreateThread(
NULL, // Pointer to thread security attributes
0, // Initial thread stack size, in bytes
WorkerFunction, // Pointer to thread function
&threadParm, // The argument for the new thread
0, // Creation flags
&dwThreadID // Pointer to returned thread identifier
);
// Wait for the call to InternetConnect in worker function to complete
dwTimeout = 5000; // in milliseconds
if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT )
{
cout << "Can not connect to server in "
<< dwTimeout << " milliseconds" << endl;
if ( g_hOpen )
InternetCloseHandle ( g_hOpen );
// Wait until the worker thread exits
WaitForSingleObject ( hThread, INFINITE );
cout << "Thread has exited" << endl;
return ;
}
// The state of the specified object (thread) is signaled
dwExitCode = 0;
if ( !GetExitCodeThread( hThread, &dwExitCode ) )
{
cerr << "Error on GetExitCodeThread: " << GetLastError() << endl;
return ;
}
CloseHandle (hThread);
if ( dwExitCode )
// Worker function failed
return ;
if ( !FtpGetFile ( g_hConnect,
szRemoteFile,
szLocalFile,
FALSE,INTERNET_FLAG_RELOAD,
FTP_TRANSFER_TYPE_ASCII,
0 ) )
{
cerr << "Error on FtpGetFile: " << GetLastError() << endl;
return ;
}
if ( g_hConnect )
InternetCloseHandle( g_hConnect );
if ( g_hOpen )
InternetCloseHandle( g_hOpen );
return ;
}
/// WorkerFunction //
DWORD WINAPI
WorkerFunction(
IN LPVOID vThreadParm
)
/*
Purpose:
Call InternetConnect to establish a FTP session
Arguments:
vThreadParm - points to PARM passed to thread
Returns:
returns 0
*/
{
PARM* pThreadParm;
// Initialize local pointer to void pointer passed to thread
pThreadParm = (PARM*)vThreadParm;
g_hConnect = 0;
if ( !( g_hConnect = InternetConnect (
g_hOpen,
pThreadParm->pHost,
INTERNET_INVALID_PORT_NUMBER,
pThreadParm->pUser,
pThreadParm->pPass,
INTERNET_SERVICE_FTP,
0,
0 ) ) )
{
cerr << "Error on InternetConnnect: " << GetLastError() << endl;
return 1; // failure
}
return 0; // success
}