青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Benjamin

靜以修身,儉以養(yǎng)德,非澹薄無(wú)以明志,非寧?kù)o無(wú)以致遠(yuǎn)。
隨筆 - 398, 文章 - 0, 評(píng)論 - 196, 引用 - 0
數(shù)據(jù)加載中……

WinInet編程中如何使用異步

在WinInet編程中,同步的使用方法如下:
InternetOpen->InternetOpenUrl->HttpQueryInfo->InternetReadFile->InternetCloseHandle;在InternetOpenUrl和InternetReadFile時(shí)會(huì)導(dǎo)致程序阻塞,知道操作完成,同步的好處就是比較簡(jiǎn)單,調(diào)試方便。
異步的使用方法如下:
1)InternetOpen,需指定是異步;
2)InternetSetStatusCallback,設(shè)置回調(diào);
3)InternetOpenUrl,需指定回調(diào)參數(shù);
4)WaitForSingObject或WaitForMultipleObjects,接收信號(hào)量;
5)HttpQueryInfo;
6)InternetReadFileEx,需指定回調(diào)參數(shù)(CE或mobile下是InternetReadFileExA);
7)WaitForSingObject或WaitForMultipleObjects,接收信號(hào)量;
8)InternetSetStatusCallback,卸載回調(diào);
9)InternetCloseHandle。
異步比同步要復(fù)雜了不少,重點(diǎn)在于回調(diào)函數(shù)。在回調(diào)中,系統(tǒng)會(huì)及時(shí)返回各種系統(tǒng)定義的HTTP消息,我們根據(jù)這些消息來(lái)設(shè)置某些信號(hào)量。在WaitForSingObject或WaitForMultipleObjects里,等待這些信號(hào)(當(dāng)然也可以等待用戶的取消動(dòng)作)。當(dāng)有正確的信號(hào)返回時(shí),繼續(xù)往下的操作。下面一個(gè)例子代碼:上面的理論同樣適用于wince或windows mobile平臺(tái)

#include<windows.h>
#include
<wininet.h>
#include
<iostream.h>

DWORD dwNumKSent;
DWORD dwNumKToSend;
DWORD dwNumBytesComplete 
= 0;
char lpOutBuf[1024];
HANDLE hConnectedEvent, hRequestCompleteEvent;
HINTERNET hInstance, hConnect, hRequest;
char *lpszUrl, *lpszServer;

BOOL bAllDone 
= FALSE;

void __stdcall Callback(HINTERNET hInternet,
              DWORD dwContext,
              DWORD dwInternetStatus,
              LPVOID lpStatusInfo,
              DWORD dwStatusInfoLen);

void main(int argc, char *argv[])
{
    
if (argc != 4)
    {
        cout 
<< "Usage: sendreqexasync <server> <url> <size in kilobytes>" << endl;
        cout 
<< "   Example: sendreqexasync www.foo.com /postfolder/upload.exe 256" << endl;
        
return;
    }

    lpszServer 
= argv[1];
    lpszUrl 
= argv[2];
    dwNumKToSend 
= atoi(argv[3]);

    FillMemory(lpOutBuf, 
1024'A');
    hConnectedEvent 
= CreateEvent(NULL, FALSE, FALSE, NULL);
    hRequestCompleteEvent 
= CreateEvent(NULL, FALSE, FALSE, NULL);

    hInstance 
= InternetOpen("sendreqexasync"
                                       INTERNET_OPEN_TYPE_PRECONFIG,
                                       NULL,
                                       NULL,
                                       INTERNET_FLAG_ASYNC);

    
if (hInstance == NULL)
    {
        cout 
<< "InternetOpen failed, error " << GetLastError();
        
return;
    }

    
if (InternetSetStatusCallback(hInstance,
                                  (INTERNET_STATUS_CALLBACK)
&Callback) == INTERNET_INVALID_STATUS_CALLBACK)
    {
        cout 
<< "InternetSetStatusCallback failed, error " << GetLastError();
        
return;
    }

    hConnect 
= InternetConnect(hInstance, 
                               lpszServer, 
                               INTERNET_DEFAULT_HTTP_PORT,
                               NULL,
                               NULL,
                               INTERNET_SERVICE_HTTP,
                               
0,
                               
1);
    
if (hConnect == NULL)
    {
        
if (GetLastError() != ERROR_IO_PENDING)
        {
            cout 
<< "InternetConnect failed, error " << GetLastError();
            
return;
        }
        WaitForSingleObject(hConnectedEvent, INFINITE);
    }

    hRequest 
= HttpOpenRequest(hConnect, 
                               
"POST"
                               lpszUrl,
                               NULL,
                               NULL,
                               NULL,
                               INTERNET_FLAG_RELOAD 
| INTERNET_FLAG_NO_CACHE_WRITE,
                               
2);
    
if (hRequest == NULL)
    {
        
if (GetLastError() != ERROR_IO_PENDING)
        {
            cout 
<< "HttpOpenRequest failed, error " << GetLastError();
            
return;
        }
        WaitForSingleObject(hRequestCompleteEvent, INFINITE);
    }

    INTERNET_BUFFERS IntBuff;

    FillMemory(
&IntBuff, sizeof(IntBuff), 0);
    IntBuff.dwStructSize
= sizeof(IntBuff);
    IntBuff.dwBufferTotal 
= 1024*dwNumKToSend;
    IntBuff.lpcszHeader 
= "Content-Type: text/text\r\n";
    IntBuff.dwHeadersLength 
= lstrlen(IntBuff.lpcszHeader);

    
if (!HttpSendRequestEx(hRequest, 
                           
&IntBuff, 
                           NULL, 
                           
0,
                           
2))
    {
        
if (GetLastError() != ERROR_IO_PENDING)
        {
            cout 
<< "HttpSendRequestEx failed, error " << GetLastError();
            
return;
        }
        cout 
<< "HttpSendRequestEx called successfully" << endl;
        cout.flush();

        WaitForSingleObject(hRequestCompleteEvent, INFINITE);
    }

    
for (dwNumKSent = 0; dwNumKSent < dwNumKToSend; dwNumKSent++)
    {
        DWORD dwBytesWritten;

        
if(!InternetWriteFile(hRequest,
                               lpOutBuf,
                               
1024,
                               
&dwBytesWritten))
        {
            
if (GetLastError() != ERROR_IO_PENDING)
            {
                cout 
<< "InternetWriteFile failed, error " << GetLastError();
                
return;
            }
            
else
            {
                cout 
<< "InternetWriteFile completing asynchronously" << endl;
                cout.flush();
                WaitForSingleObject(hRequestCompleteEvent, INFINITE);
            }
        }
    }

    cout 
<< "Calling HttpEndRequest" << endl;
    cout.flush();
    
if (!HttpEndRequest(hRequest, NULL, HSR_INITIATE, 2))
    {
        
if (GetLastError() == ERROR_IO_PENDING)
        {
            cout 
<< "HttpEndRequest called" << endl;
            cout.flush();
            WaitForSingleObject(hRequestCompleteEvent, INFINITE);
        }
        
else
        {
            cout 
<< "HttpEndRequest failed, error " << GetLastError() << endl;
            
return;
        }
    }


    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;
        
        cout 
<< "Calling InternetReadFileEx" << endl;
        cout.flush();

        
if (!InternetReadFileEx(hRequest,
                              
&InetBuff,
                              
02))
        {
            
if (GetLastError() == ERROR_IO_PENDING)
            {
                cout 
<< "Waiting for InternetReadFile 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)
{
    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;
            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;
                cout 
<< "Request handle created" << endl;
                cout.flush();
            }
            
break;
        
case INTERNET_STATUS_REQUEST_SENT:
            {
                DWORD 
*lpBytesSent = (DWORD*)lpStatusInfo;
                cout 
<< "Bytes Sent: " << *lpBytesSent << endl;
                dwNumBytesComplete 
+= *lpBytesSent;
            }
            
break;
        
case INTERNET_STATUS_REQUEST_COMPLETE:
            {
                INTERNET_ASYNC_RESULT 
*pAsyncRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
                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:
            cout 
<< "Receiving Response" << endl;
            cout.flush();
            
break;
        
case INTERNET_STATUS_RESPONSE_RECEIVED:
            {
                DWORD 
*dwBytesReceived = (DWORD*)lpStatusInfo;
                cout 
<< "Received " << *dwBytesReceived << endl;
                cout.flush();
            }

        }

    }

}

參考的異步類:
 1 include <wininet.h>
 2 #include <mmsystem.h>
 3 
 4 class AsyncWinINet
 5 {
 6 public:
 7    typedef void (*notify_fp)(const StringMap&);
 8   
 9    class thread_info
10    {
11    public:
12     thread_info(const String& _url,     //請(qǐng)求下載的地址(in)
13      const StringMap& _request_headrs,   //請(qǐng)求頭request_headrs(in)
14      const notify_fp& _pfp,      //下載進(jìn)度通知回調(diào)函數(shù)指針
15      const StringMap& _pfp_param,
16      String& _response_headrs,     //返回頭response_headrs(out)  
17      const String& _saved_filename,    //下載內(nèi)容保存文件名(in)
18      String& _response_content,     //返回內(nèi)容(out)
19      size_t _read_content_size)     //控制保存在response_content中內(nèi)容的長(zhǎng)度(in)) : 
20      : request_headrs(_request_headrs), pfp(_pfp),
21      pfp_param(_pfp_param),      //pfp函數(shù)傳回參數(shù)
22      response_headrs(_response_headrs), saved_filename(_saved_filename),
23      response_content(_response_content), read_content_size(_read_content_size) 
24     {
25      this->response_headrs.clear();
26      this->response_content.clear();
27      this->url = StringUtil::EncodeURIComponent(_url);
28      for(int i = 0; i < 3++i)
29      {
30       this->hEvent[i] = CreateEvent(NULL,TRUE,FALSE,NULL);
31      }
32     }
33 
34     HANDLE hThread;
35     DWORD dwThreadID;
36     HANDLE hCallbackThread;
37     DWORD dwCallbackThreadID;
38     HANDLE hEvent[3];
39     LPVOID hInternet;
40     LPVOID hFile;
41     DWORD dwStatusCode;
42     DWORD dwContentLength;
43 
44     String url;         //請(qǐng)求下載的地址(in)
45     const StringMap& request_headrs;   //請(qǐng)求頭request_headrs(in)
46     const notify_fp& pfp;      //下載進(jìn)度通知回調(diào)函數(shù)指針
47     const StringMap& pfp_param;     //pfp函數(shù)傳回參數(shù)
48 
49     String& response_headrs;     //返回頭response_headrs(out)  
50     const String& saved_filename;    //下載內(nèi)容保存文件名(in)
51     String& response_content;     //返回內(nèi)容(out)
52     size_t read_content_size;     //控制保存在response_content中內(nèi)容的長(zhǎng)度(in)
53    };
54 
55    /*******************************************************************************
56    * 函數(shù):download
57    * 功能:下載,返回WinINet_ERR_CODE值
58    *   說(shuō)明:關(guān)于notify_fp 類型說(shuō)明: 函數(shù)的參數(shù)為StringMap類型,傳回的變量名與變量值
59    * 2007-12
60    *******************************************************************************/
61    static DWORD download(const String& url, //請(qǐng)求下載的地址(in)
62     const StringMap& request_headrs,   //請(qǐng)求頭request_headrs(in)
63     const notify_fp& pfp,      //下載進(jìn)度通知回調(diào)函數(shù)指針
64     const StringMap& pfp_param,     //pfp函數(shù)傳回參數(shù)
65     String& response_headrs,     //返回頭response_headrs(out)  
66     const String& saved_filename,    //下載內(nèi)容保存文件名(in)
67     String& response_content,     //返回內(nèi)容(out)
68     size_t read_content_size = 0);    //控制保存在response_content中內(nèi)容的長(zhǎng)度(in)
69 
70 protected:
71    static BOOL WaitExitEvent(thread_info *p);
72    static DWORD WINAPI AsyncThread(LPVOID lpParameter);
73    static DWORD WINAPI AsyncCallbackThread(LPVOID lpParameter);
74    static VOID CALLBACK AsyncInternetCallback(HINTERNET hInternet,
75     DWORD dwContext,
76     DWORD dwInternetStatus,
77     LPVOID lpvStatusInformation,
78     DWORD dwStatusInformationLength);
79 
80 };
81 

  1 #include "AsyncWinINet.h"
  2 
  3 #include "stdafx.h"
  4 
  5 #pragma comment(lib, "Winmm.lib")
  6 #pragma comment(lib, "Wininet.lib")
  7 
  8 DWORD AsyncWinINet::download(const Fagex::String &url, const Fagex::StringMap &request_headrs, 
  9    const Fagex::AsyncWinINet::notify_fp &pfp, const Fagex::StringMap &pfp_param, Fagex::String &response_headrs, 
 10    const Fagex::String &saved_filename, Fagex::String &response_content, size_t read_content_size)
 11 {
 12    thread_info info(url, request_headrs, pfp,
 13     pfp_param, response_headrs, saved_filename,
 14     response_content, read_content_size);
 15 
 16    info.hThread = CreateThread(NULL, 
 17     0,
 18     AsyncWinINet::AsyncThread,
 19     &info,
 20     NULL,
 21     &info.dwThreadID);
 22 
 23    WaitForSingleObject(info.hThread, INFINITE); //等待子線程安全退出
 24    CloseHandle(info.hThread);//關(guān)閉線程句柄
 25 
 26    return TRUE;
 27 }
 28 
 29 //---------------------------------------------------------------------
 30 DWORD WINAPI AsyncWinINet::AsyncThread(LPVOID lpParameter)
 31 {
 32    thread_info* p = (thread_info*)lpParameter;
 33 
 34    //a. 使用標(biāo)記 INTERNET_FLAG_ASYNC 初始化 InternetOpen
 35    String user_agent("Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler ; .NET CLR 2.0.50727)");
 36    StringMap iheadrs(p->request_headrs.begin(), p->request_headrs.end());
 37    StringMap::iterator it = iheadrs.find("User-Agent");
 38    if(it == iheadrs.end()) iheadrs["User-Agent"= user_agent;
 39    else user_agent = it->second;
 40 
 41    p->hInternet = InternetOpen(user_agent.c_str(),
 42     INTERNET_OPEN_TYPE_PRECONFIG,
 43     NULL,
 44     NULL,
 45     INTERNET_FLAG_ASYNC);
 46 
 47    //ResetEvent(p->hEvent[0]);
 48    //p->hCallbackThread = CreateThread(NULL,
 49    // 0,
 50    // AsyncWinINet::AsyncCallbackThread,
 51    // p,
 52    // NULL,
 53    // &p->dwCallbackThreadID);
 54    //WaitForSingleObject(p->hEvent[0], INFINITE);//等待回調(diào)函數(shù)設(shè)置成功事件
 55    InternetSetStatusCallback(p->hInternet, AsyncWinINet::AsyncInternetCallback);
 56 
 57    String sheadrs;
 58    for(it = iheadrs.begin(); it != iheadrs.end(); ++it)
 59    {
 60     sheadrs += it->first + ":" + it->second;
 61     if(it->second.find(StringUtil::enter) == String::npos) { sheadrs += StringUtil::enter; }
 62    }
 63    sheadrs += StringUtil::enter;
 64   
 65    DWORD start_time = timeGetTime();
 66    ResetEvent(p->hEvent[0]); //重置句柄被創(chuàng)建事件
 67    p->hFile = InternetOpenUrl(p->hInternet, p->url.c_str(), sheadrs.c_str(), sheadrs.length(), 
 68     INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD, (DWORD)p);
 69 
 70    FILE *fp = fopen(p->saved_filename.c_str(), "w+");
 71    while(true)
 72    {
 73     if (NULL == p->hFile)
 74     {
 75      DWORD dwError = ::GetLastError();
 76      if (ERROR_IO_PENDING == dwError || ERROR_SUCCESS == dwError)
 77      {
 78       if (WaitExitEvent(p)) { break; }
 79      }
 80      else break;
 81     }
 82 
 83     //讀取返回文件頭
 84     DWORD dwLength = 0;
 85     LPVOID lpOutBuffer = NULL;
 86     while(true//讀取response_headrs數(shù)據(jù)
 87     {
 88      if(!HttpQueryInfo(p->hFile, HTTP_QUERY_RAW_HEADERS_CRLF,
 89         lpOutBuffer, &dwLength, NULL))
 90      {
 91       DWORD err_code = GetLastError();
 92       if (err_code == ERROR_HTTP_HEADER_NOT_FOUND) break
 93       else if(err_code == ERROR_INSUFFICIENT_BUFFER)
 94       {
 95        lpOutBuffer = new char[dwLength];
 96        continue
 97       }
 98       else break;
 99      }
100      break;
101     }
102     if(lpOutBuffer != NULL)
103     {
104      p->response_headrs.append((char*)lpOutBuffer,dwLength);
105      delete [] lpOutBuffer;
106     }
107 
108     //e. 使用 HttpQueryInfo 分析頭信息 HttpQueryInfo 使用非阻塞方式,所以不用等待
109     DWORD dwStatusSize = sizeof(p->dwStatusCode);
110     if (FALSE == HttpQueryInfo(p->hFile, //獲取返回狀態(tài)碼
111      HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
112      &p->dwStatusCode, &dwStatusSize, NULL)) { break; }
113    
114     //判斷狀態(tài)碼是不是 200
115     if (HTTP_STATUS_OK != p->dwStatusCode) break;
116    
117     StringMap msgMap(p->pfp_param.begin(), p->pfp_param.end());
118     msgMap["url"= p->url;
119 
120     //獲取返回的Content-Length
121     //DWORD dwLengthSize = sizeof(p->dwContentLength); 
122     //if (FALSE == HttpQueryInfo(p->hFile,
123     //HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
124     //&p->dwContentLength, &dwLengthSize, NULL)) { p->dwContentLength = 0; }
125 
126     //f. 使用標(biāo)記 IRF_ASYNC 讀數(shù)據(jù) InternetReadFileEx
127     //為了向主線程報(bào)告進(jìn)度,我們?cè)O(shè)置每次讀數(shù)據(jù)最多 1024 字節(jié)
128 
129     char lpvBuffer[1024];
130     p->dwContentLength = 0//Content-Length: 202749
131     while(true)
132     {
133      INTERNET_BUFFERS i_buf = {0};
134      i_buf.dwStructSize = sizeof(INTERNET_BUFFERS);
135      i_buf.lpvBuffer = lpvBuffer;
136      i_buf.dwBufferLength = 1024;
137        
138      //重置讀數(shù)據(jù)事件
139      ResetEvent(p->hEvent[0]);
140      if (FALSE == InternetReadFileEx(p->hFile, &i_buf, IRF_ASYNC, (DWORD)p))
141      {
142       if (ERROR_IO_PENDING == ::GetLastError())
143       {
144        if (WaitExitEvent(p)) break
145       }
146       else break
147      }
148      else
149      {
150       //在網(wǎng)絡(luò)傳輸速度快,步長(zhǎng)較小的情況下,InternetReadFileEx 經(jīng)常會(huì)直接返回成功,
151       //因此要判斷是否發(fā)生了用戶要求終止子線程事件。
152       if (WAIT_OBJECT_0 == WaitForSingleObject(p->hEvent[2], 0))
153       {
154        ResetEvent(p->hEvent[2]);
155        break;
156       }
157      }
158 
159      if(i_buf.dwBufferLength == 0
160      {
161       DWORD time = timeGetTime() - start_time;
162       if(time != 0)
163       {
164        Real speed = (Real)p->dwContentLength;
165        speed /= ((Real)time)/1000.0f;
166        speed /= 1024.0f;
167        msgMap["speed"= StringUtil::toString((DWORD)speed);
168       }
169       if(p->pfp) p->pfp(msgMap);
170       break;
171      }
172      if(fp)
173      {
174       fwrite(i_buf.lpvBuffer, sizeof(char), i_buf.dwBufferLength, fp);
175      }
176      if(p->read_content_size > p->response_content.size())
177      {
178       p->response_content.append((char*)i_buf.lpvBuffer, i_buf.dwBufferLength);
179      }
180      p->dwContentLength += i_buf.dwBufferLength;
181     }
182     break;
183    }
184   
185    if(fp)
186    {
187     fflush(fp); fclose(fp); fp = NULL;
188    }
189 
190    if(p->hFile)
191    {
192     InternetCloseHandle(p->hFile);//關(guān)閉 m_hFile
193     while (!WaitExitEvent(p)) //等待句柄被關(guān)閉事件或者要求子線程退出事件
194     {
195      ResetEvent(p->hEvent[0]);
196     }
197    }
198 
199    //設(shè)置子線程退出事件,通知回調(diào)線程退出
200    SetEvent(p->hEvent[2]);
201   
202    //等待回調(diào)線程安全退出
203    //WaitForSingleObject(p->hCallbackThread, INFINITE);
204    //CloseHandle(p->hCallbackThread);
205   
206    //注銷回調(diào)函數(shù)
207    InternetSetStatusCallback(p->hInternet, NULL);
208    InternetCloseHandle(p->hInternet);
209 
210    return TRUE;
211 }
212 
213 //------------------------------------------------------------------------------------
214 DWORD WINAPI AsyncWinINet::AsyncCallbackThread(LPVOID lpParameter)
215 {
216    thread_info *= (thread_info*)lpParameter;
217    InternetSetStatusCallback(p->hInternet, AsyncWinINet::AsyncInternetCallback);
218 
219    //通知子線程回調(diào)函數(shù)設(shè)置成功,子線程可以繼續(xù)工作
220    SetEvent(p->hEvent[0]);
221 
222    //等待用戶終止事件或者子線程結(jié)束事件
223    //子線程結(jié)束前需要設(shè)置子線程結(jié)束事件,并等待回調(diào)線程結(jié)束
224    WaitForSingleObject(p->hEvent[2], INFINITE);
225 
226    return 0;
227 }
228 
229 //----------------------------------------------------------------------------
230 VOID CALLBACK AsyncWinINet::AsyncInternetCallback(HINTERNET hInternet,
231     DWORD dwContext,
232     DWORD dwInternetStatus,
233     LPVOID lpvStatusInformation,
234     DWORD dwStatusInformationLength)
235 {
236    thread_info* p = (thread_info*)dwContext;
237   
238    //在我們的應(yīng)用中,我們只關(guān)心下面三個(gè)狀態(tài)
239    switch(dwInternetStatus)
240    {
241    //句柄被創(chuàng)建
242    case INTERNET_STATUS_HANDLE_CREATED:
243     p->hFile = (HINTERNET)(((LPINTERNET_ASYNC_RESULT)
244      (lpvStatusInformation))->dwResult);
245     break;
246   
247    //句柄被關(guān)閉
248    case INTERNET_STATUS_HANDLE_CLOSING:
249     SetEvent(p->hEvent[1]);
250     break;
251 
252    //一個(gè)請(qǐng)求完成,比如一次句柄創(chuàng)建的請(qǐng)求,或者一次讀數(shù)據(jù)的請(qǐng)求
253    case INTERNET_STATUS_REQUEST_COMPLETE:
254     if (ERROR_SUCCESS == ((LPINTERNET_ASYNC_RESULT)
255      (lpvStatusInformation))->dwError)
256     { 
257      //設(shè)置句柄被創(chuàng)建事件或者讀數(shù)據(jù)成功完成事件
258      SetEvent(p->hEvent[0]);
259     }
260     else
261     { 
262      //如果發(fā)生錯(cuò)誤,則設(shè)置子線程退出事件 這里也是一個(gè)陷阱,經(jīng)常會(huì)忽視處理這個(gè)錯(cuò)誤,
263      SetEvent(p->hEvent[2]);
264     }
265     break;
266 
267    case INTERNET_STATUS_CONNECTION_CLOSED:
268     SetEvent(p->hEvent[2]);
269     break;
270 
271    }
272 }
273 
274 //--------------------------------------------------------------------
275 BOOL AsyncWinINet::WaitExitEvent(thread_info *p)
276 {
277    DWORD dwRet = WaitForMultipleObjects(3, p->hEvent, FALSE, INFINITE);
278   
279    switch (dwRet)
280    {
281    case WAIT_OBJECT_0://句柄被創(chuàng)建事件或者讀數(shù)據(jù)請(qǐng)求成功完成事件
282    case WAIT_OBJECT_0+1://句柄被關(guān)閉事件
283    case WAIT_OBJECT_0+2://用戶要求終止子線程事件或者發(fā)生錯(cuò)誤事件
284     break;
285    }
286    return WAIT_OBJECT_0 != dwRet;
287 }
288 

posted on 2009-05-17 16:33 Benjamin 閱讀(11794) 評(píng)論(15)  編輯 收藏 引用 所屬分類: VC

評(píng)論

# 我暈就是太崇拜!!!  回復(fù)  更多評(píng)論   

暫時(shí)失去意識(shí)。
2009-09-11 20:09 | 感嘆12345678

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

寫的非常不錯(cuò),感謝!
2009-12-18 14:53 | xuqs

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

寫得很好,給我?guī)椭艽螅x謝!
2010-08-19 17:36 | lvcayu

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

請(qǐng)問(wèn)有代碼工程嗎,發(fā)給我一份好嗎?267358440@qq.com,謝謝您了!
2010-08-28 17:43 | 學(xué)習(xí)

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

Wince下異步使用InternetReadFileEx就不可以,lz說(shuō)可以,不知是否有試驗(yàn)過(guò),應(yīng)該改為InternetReadFileExA才可
2011-04-18 11:28 | 4321

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

@4321
僅僅WinCE下InternetReadFileEx未實(shí)現(xiàn)而已
2011-04-18 12:37 | 溪流

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

Wince下我發(fā)現(xiàn)句柄關(guān)閉時(shí)回調(diào)函數(shù)也沒有
InternetStates:70 即INTERNET_STATUS_HANDLE_CLOSING,這個(gè)該如何解決
2011-04-18 17:13 | 4321

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

CE或mobile下的異步要用InternetReadFileExA,也可以多線程實(shí)現(xiàn);
2011-04-18 22:36 | Benjamin

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

@Benjamin
多線程不是很好吧,要是在多線程的同步下讀取數(shù)據(jù)的函數(shù)阻塞了會(huì)把線程給卡死,強(qiáng)制退出線程問(wèn)題多多啊。
還是想問(wèn)
Wince下句柄關(guān)閉時(shí)回調(diào)函數(shù)沒有接收到
InternetStates:70 即INTERNET_STATUS_HANDLE_CLOSING 消息,這個(gè)該怎么解決
2011-04-19 10:05 | 4321

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

這些代碼怎么寫的啊,好難
2011-07-19 17:36 |

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

http://blog.csdn.net/achellies/article/details/4569456
2011-09-27 18:28 | daixi

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

不好意思,直接Ctrl+Enter就發(fā)出去了,悲摧。。。

http://blog.csdn.net/achellies/article/details/4569456

這篇文章里面說(shuō),直接使用InternetConenect會(huì)有問(wèn)題,不知道博主有研究過(guò)嗎?我想多學(xué)習(xí)一下,謝謝。。
2011-09-27 18:29 | daixi

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

作者的思路有嚴(yán)重問(wèn)題,完全沒有利用到異步的優(yōu)勢(shì),用WaitForSingleObject等在那里,跟同步有啥區(qū)別啊,還不如用同步方式處理了。回調(diào)函數(shù)難道就是給你用來(lái)設(shè)置事件的?

真正的異步是不需要等的,數(shù)據(jù)的處理放在回調(diào)中進(jìn)行,完全不用等待。
2012-02-20 16:14 | famu

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

@famu
可以讓線程掛起,釋放cpu資源。
2013-01-07 10:43 | yoooooo

# re: WinInet編程中如何使用異步  回復(fù)  更多評(píng)論   

說(shuō)是異步,其實(shí)還是WAIT等同步方式,此乃非真正的異步
2015-09-08 11:01 | 無(wú)名氏
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美成人精品1314www| 欧美日本免费| 国内精品久久久久久| 久久精品视频亚洲| 欧美一区二区三区日韩视频| 9色porny自拍视频一区二区| av成人老司机| 亚洲在线电影| 伊人久久噜噜噜躁狠狠躁 | 亚洲图片欧美午夜| 夜色激情一区二区| 国产精品a久久久久久| 午夜在线视频观看日韩17c| 欧美一区二区三区四区在线| 国产一区二区在线观看免费播放| 久久aⅴ国产欧美74aaa| 男女精品网站| 噜噜噜躁狠狠躁狠狠精品视频 | 国产精品一国产精品k频道56| 久久精品亚洲精品| 欧美视频精品一区| 亚洲乱码精品一二三四区日韩在线| 亚洲欧美精品伊人久久| 欧美成人激情在线| 国产欧美视频一区二区| 99国产精品| 日韩亚洲欧美一区| 麻豆精品91| 欧美激情精品久久久久久大尺度 | 亚洲三级观看| 国产精品极品美女粉嫩高清在线 | 亚洲国产99| 久久只精品国产| 亚洲国产精品va在线看黑人| 国产综合视频在线观看| 国产精品久久久久久久久久久久| 999亚洲国产精| 欧美经典一区二区| 欧美激情一区二区三区在线视频| 欧美精彩视频一区二区三区| 欧美激情亚洲视频| 亚洲尤物在线| 欧美精品免费播放| 午夜精品av| 欧美激情一区二区三区四区| 亚洲乱码精品一二三四区日韩在线| 久久九九有精品国产23| 亚洲精品乱码久久久久久日本蜜臀| 亚洲欧洲在线看| 国产伦精品一区二区三区高清| 亚洲欧美日韩国产综合精品二区| 久久久久久久网站| 一区二区三区www| 在线免费观看日本一区| 欧美区视频在线观看| 一区二区三区欧美| 亚洲免费影视第一页| 亚洲国产天堂久久国产91| 国产精品扒开腿做爽爽爽视频 | 欧美一级在线视频| 亚洲第一在线| 久久久久国产精品麻豆ai换脸| 一本色道久久| 91久久一区二区| 国产欧美精品国产国产专区| 欧美激情精品久久久久久蜜臀 | 国产精品成av人在线视午夜片| 欧美福利专区| 女人色偷偷aa久久天堂| 女仆av观看一区| 欧美激情日韩| 亚洲国产aⅴ天堂久久| 免费一级欧美在线大片| 久久久久久久一区二区| 亚洲精华国产欧美| 亚洲国产日韩精品| 亚洲乱码一区二区| 99精品黄色片免费大全| aa国产精品| 欧美一区二区三区在线视频 | 国产欧美日韩在线观看| 好吊一区二区三区| 亚洲国产高清在线| 一区二区av在线| 久久久久高清| 久久成年人视频| 99精品视频免费在线观看| 在线视频欧美日韩| 久久精品国产999大香线蕉| 欧美a级大片| 国产精品一区亚洲| 亚洲国产精品ⅴa在线观看| 亚洲午夜小视频| 久久综合给合久久狠狠狠97色69| 男同欧美伦乱| 夜夜嗨av一区二区三区中文字幕 | 欧美一区二区三区免费视频| 久久久蜜桃一区二区人| 国产欧美精品日韩精品| 亚洲清纯自拍| 欧美大片在线观看一区| 免费日韩一区二区| 欧美69视频| 亚洲经典一区| 欧美va亚洲va香蕉在线| 欧美在线免费观看视频| 欧美日韩国产91| 亚洲一区二区精品| 一区二区精品| 国产精品综合视频| 欧美在线高清视频| 欧美日韩国产一中文字不卡 | 欧美一级大片在线免费观看| 亚洲精品视频一区| 欧美精品一区二区三区在线看午夜 | 国产欧美日韩精品在线| 亚洲电影在线播放| 欧美成人国产| 欧美成人一区二区三区片免费| 亚洲国产专区| 亚洲久久成人| 国产麻豆精品视频| 久久精品一二三区| 久久精品免费看| 亚洲免费av电影| 亚洲视频精选| 91久久精品www人人做人人爽| 亚洲国内自拍| 国语自产偷拍精品视频偷 | 久久久久国产免费免费| 亚洲人成人77777线观看| 亚洲综合不卡| 亚洲精品国产品国语在线app| 亚洲视频在线观看视频| 亚洲欧美中文另类| 亚洲专区在线| 亚洲手机在线| 欧美韩国在线| 欧美中文字幕不卡| 欧美四级剧情无删版影片| 美女精品国产| 亚洲大片av| 久久黄色影院| 噜噜噜久久亚洲精品国产品小说| 欧美性猛交99久久久久99按摩| 麻豆av福利av久久av| 亚洲欧美激情一区| 欧美成人一区二区三区在线观看| 久久精品二区亚洲w码| 国产精品一区二区欧美| 亚洲小少妇裸体bbw| 亚洲欧美视频在线| 国产精品一区二区在线观看网站 | 午夜精品久久久久久| 欧美日韩1080p| 亚洲图片欧美午夜| 欧美一级黄色录像| 欧美网站大全在线观看| 亚洲国产mv| 一本色道久久综合狠狠躁的推荐| 欧美日韩精品在线视频| 一二三区精品| 欧美成人免费观看| 亚洲视频一起| 精品粉嫩aⅴ一区二区三区四区| 欧美在线视频观看免费网站| 欧美国产日韩一区二区在线观看| 亚洲欧洲另类| 国产在线观看精品一区二区三区| 久久精品一二三区| 一区二区三区精品国产| 亚洲精品一区二| 午夜亚洲性色福利视频| 午夜视频精品| 亚洲国产精品悠悠久久琪琪| 亚洲国产一区二区三区在线播| 久久se精品一区精品二区| 伊人久久婷婷| 国产精品jizz在线观看美国 | 亚洲美女色禁图| 亚洲国产经典视频| 欧美理论电影网| 久久久久久久网站| 亚洲欧美在线高清| 中文在线不卡| 99日韩精品| 亚洲六月丁香色婷婷综合久久| 免费在线成人| 亚洲第一在线| 亚洲国产精品一区二区第一页 | 欧美成人精品h版在线观看| 久久亚洲精品网站| 久久久久久久综合| 老司机免费视频一区二区三区| 午夜欧美理论片| 欧美一级大片在线观看| 亚洲一区二区在线视频| 香蕉国产精品偷在线观看不卡| 欧美一区二区精美| 欧美不卡在线视频|