关于WININET的异步使用的代码和一些相关知识

全部转自 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();  
                }  
            }  
 
        }  
 
    }  
 

如何通过创建另一个线程控制连接超时值(转自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  
   } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值