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

隨筆 - 2, 文章 - 73, 評論 - 60, 引用 - 0
數(shù)據(jù)加載中……

Using WinInet HTTP functions in Full Asynchronous Mode

Introduction

If you have ever dug into the MSDN for WinInet API, you noticed that it can be used asynchronously and that it is the recommended way to use it.

If then you decide to use it, you won’t find any explanation of how to use it asynchronously. And no samples are available anywhere on Internet. After a long research and lots of testing, I finally managed to reconstruct a big part of the (voluntary?) missing documentation.

Why asynchronous is better? Because it can handle timeouts correctly. Just what’s missing in WinInet under IE5.5.

If you try to use TerminateThread or CloseHandle functions to handle timeouts (these methods are given in MSDN articles), you’ll fall into unrecoverable leaks of all kinds.

This has been tested successfully with: IE4.01SP3, IE5.0, IE5.01, IE5.5SP1 under WinNT4 on mono and multiprocessor machines, under a stressed environment (15 concurrent instances running non-stop for 12 hours on multi-proc NT server machines).

Theory

To use WinInet functions in full asynchronous mode, you must do things in the right order:

  1. Use INTERNET_FLAG_ASYNC to open the session
  2. Set a status callback using InternetSetStatusCallback
  3. Open the connection using InternetOpenUrl
  4. If InternetOpenUrl returned NULL and GetLastError is ERROR_IO_PENDING:
    • wait for the INTERNET_STATUS_HANDLE_CREATED notification in the callback, and save the connection Handle.
    • wait for the INTERNET_STATUS_REQUEST_COMPLETE notification in the callback before going further.
  5. Extract the content-length from the header and set up an INTERNET_BUFFERS structure:
    • dwStructSize = sizeof(INTERNET_BUFFERS)
    • lpvBuffer = your allocated buffer
    • dwBufferLength = its length
  6. Use InternetReadFileEx with the IRF_ASYNC flag to read the remaining data asynchronously. Don’t use InternetReadFile since it is a synchronous function.
  7. If InternetReadFileEx returned False and GetLastError is ERROR_IO_PENDING: wait for the INTERNET_STATUS_REQUEST_COMPLETE notification in the callback before going further.

    Warning: INTERNET_BUFFERS members are modified asynchronously (only the dwBufferLength member and the content of the buffer).

  8. If the dwBufferLength member is not 0, move the lpvBuffer pointer from this amount and subtract this amount from the buffer length so dwBufferLength reflects the remaining size lpvBuffer points to, then loop to 6.
  9. Close the connection handle with InternetCloseHandle and wait for INTERNET_STATUS_HANDLE_CLOSING and the facultative INTERNET_STATUS_REQUEST_COMPLETE notification (sent only if an error occurs – like a sudden closed connection -, you must test the cases).

At this state, you can either begin a new connection process or close the session handle. But before closing it, you should un-register the callback function.

Detail

After the theory, let’s look at some code for some of the points:

1&2: Create the connection using INTERNET_FLAG_ASYNC and setup the callback func:

m_Session = InternetOpen(AGENT_NAME, INTERNET_OPEN_TYPE_PRECONFIG,
NULL, NULL, INTERNET_FLAG_ASYNC);
InternetSetStatusCallback( m_Session,
(INTERNET_STATUS_CALLBACK)InternetCallbackFunc );

3&4: Open the connection using InternetOpenUrl and wait for INTERNET_STATUS_REQUEST_COMPLETE

Use the lParam to send a session identifier to your callback. I always use the this pointer of my class for it. I assume you know how to handle callbacks.

InternetOpenUrl( m_Session, uurl, NULL, 0,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE |
INTERNET_FLAG_NO_CACHE_WRITE, (LPARAM)this );

The callback will receive a lots of messages then. Here are their orders along with the dwInternetStatus value:

[openUrl] InternetStatus: 60 INTERNET_STATUS_HANDLE_CREATED
**At this point you can save the HINTERNET handle using code like this in your callback:
INTERNET_ASYNC_RESULT* res = (INTERNET_ASYNC_RESULT*)lpvStatusInformation;
m_hHttpFile = (HINTERNET)(res->dwResult);
[openUrl] InternetStatus: 10
[openUrl] InternetStatus: 11
[openUrl] InternetStatus: 20
[openUrl] InternetStatus: 21
[openUrl] InternetStatus: 30
[openUrl] InternetStatus: 31
[openUrl] InternetStatus: 40
[openUrl] InternetStatus: 41
[openUrl] InternetStatus: 100 INTERNET_STATUS_REQUEST_COMPLETE

5: Extract the content-length and set up the INTERNET_BUFFERS structure

Once you have the handle, try to call HttpQueryInfo with HTTP_QUERY_CONTENT_LENGTH to get the size of the data to retrieve. This function can fail if the content-length field is not in the HTTP header.

Set up the INTERNET_BUFFERS structure.

INTERNET_BUFFERS ib = { sizeof(INTERNET_BUFFERS) };
ib.lpvBuffer = your allocated buffer
ib.dwBufferLength = its length

The dwBufferTotal is provided for your own use and is never modified by WinInet (as far as I know). I use it to store the total size of the received data.

6&7&8 Read the remaining data in a loop

Use InternetReadFileEx with the IRF_ASYNC flag to read the remaining data asynchronously. Don’t use InternetReadFile since it is a synchronous function. You must loop on InternetReadFileEx while the ib.dwBufferLength is not 0. Before each iteration you must adjust the lpvBuffer pointer and reset the dwBufferLength members of ib: add the received length to the pointer and set dwBufferLength to your remaining buffer size.

//Start the pump
BOOL bOk = InternetReadFileEx( m_hHttpFile, &ib, IRF_ASYNC, (LPARAM)this );
if(!bOk && GetLastError()==ERROR_IO_PENDING)
wait...
//Pump
while( bOk && ib.dwBufferLength!=0 )
{
(adjust ib values)
bOk = InternetReadFileEx( m_hHttpFile, &ib, IRF_ASYNC, (LPARAM)this );
if(!bOk && GetLastError()==ERROR_IO_PENDING)
wait...
}

Your callback should receive these notifications (maybe more than once):

[connect] InternetStatus: 40 (receiving response)
[connect] InternetStatus: 41 (response received)
[connect] InternetStatus: 50
[connect] InternetStatus: 51
and maybe
[connect] InternetStatus: 100 INTERNET_STATUS_REQUEST_COMPLETE

The last is received only if GetLastError() returned ERROR_IO_PENDING. If you stored the total data size (in bytes) in the dwBufferTotal member, use it to set the final “0” in your string buffer (if it’s a string).

buf[ib.dwBufferTotal] = 0;

9 Close the connection handle

InternetCloseHandle( m_httpFile );

The callback will receive this notification when the handle is closed:

[connect] InternetStatus: 70 INTERNET_STATUS_HANDLE_CLOSING

In most error cases, the connection is closed unexpectedly. If it happens you’ll receive a 70 followed by a 100 (INTERNET_STATUS_REQUEST_COMPLETE). This can happen anywhere during the process.

10 Before closing the m_Session handle

You must deregister the callback:

InternetSetStatusCallback( m_Session, NULL );

This should help those who tried to go through asynchronous mode in WinInet! Sorry, there are no attached files but you should be able to use the functions and create nice classes now. If you liked this article please add an entry in my guestbook and buy me a license of my shareware.

Bibliography

About the Author

Benjamin Mayrargue



Location: United States United States

Other popular Internet / Network articles:

posted on 2007-12-20 13:49 郭天文 閱讀(2462) 評論(0)  編輯 收藏 引用 所屬分類: VC++Windows Mobile

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产欧美在线| 久久精品99久久香蕉国产色戒| 欧美一区二区三区日韩| 99av国产精品欲麻豆| 亚洲精品视频一区| 亚洲日本久久| 亚洲少妇中出一区| 欧美亚洲免费| 久久这里有精品视频| 欧美第一黄色网| 精品1区2区| 在线观看亚洲专区| 亚洲福利视频二区| 一本一本久久a久久精品牛牛影视| 一区二区三区色| 性欧美18~19sex高清播放| 久久久天天操| 99国产精品久久久久久久久久| 午夜老司机精品| 免费成人性网站| 国产精品草莓在线免费观看| 国产欧美一级| 日韩视频二区| 久久亚洲欧洲| 一本大道久久a久久综合婷婷| 午夜日韩在线| 欧美精品一区三区| 国内精品伊人久久久久av影院| 日韩午夜av在线| 久久天堂精品| 一区二区三区**美女毛片| 久久国产婷婷国产香蕉| 欧美午夜美女看片| 亚洲国产成人在线| 久久aⅴ国产欧美74aaa| 欧美成年人网站| 亚洲欧美99| 欧美—级在线免费片| 狠狠色伊人亚洲综合网站色| 亚洲天堂av在线免费| 亚洲国产导航| 午夜在线电影亚洲一区| 欧美三级第一页| 亚洲国产一区在线| 久久精品伊人| 亚洲一区二区欧美| 欧美好骚综合网| 亚洲人成77777在线观看网| 久久久www| 亚洲欧美日韩在线综合| 欧美日韩一区二区在线观看视频| 亚洲国产经典视频| 麻豆精品一区二区av白丝在线| 欧美一级视频| 国产欧美91| 欧美亚洲在线视频| 亚洲一区二区日本| 国产精品久久久久7777婷婷| 一区二区不卡在线视频 午夜欧美不卡在 | 欧美国产日产韩国视频| 午夜亚洲一区| 国产日韩欧美在线| 国产精品国产自产拍高清av| 日韩午夜激情| 亚洲伦理一区| 欧美日本在线观看| 亚洲视频免费观看| 亚洲视频图片小说| 国产欧美精品一区二区三区介绍| 亚洲一区二区三区精品动漫| 一区二区高清视频| 国产精品红桃| 欧美一区观看| 久久久久久久成人| 亚洲人成人一区二区在线观看| 亚洲国产合集| 国产精品www网站| 久久爱www.| 久久综合狠狠综合久久综合88| 亚洲免费av观看| 亚洲男人的天堂在线aⅴ视频| 国产亚洲综合在线| 欧美成人影音| 欧美日韩精品免费观看视一区二区| 亚洲午夜小视频| 欧美在线视频免费播放| 亚洲欧洲精品一区二区精品久久久| 亚洲国产一区二区三区青草影视| 欧美特黄视频| 女仆av观看一区| 欧美性猛交一区二区三区精品| 久久九九免费视频| 欧美成人免费全部观看天天性色| 亚洲永久网站| 久久久www| 亚洲一级片在线观看| 久久久久久久一区二区| 亚洲视频视频在线| 久久久久久久久一区二区| 亚洲视频在线视频| 久久―日本道色综合久久| 亚洲午夜在线观看视频在线| 久久久精品欧美丰满| 亚洲主播在线观看| 美日韩免费视频| 欧美在线一二三四区| 欧美激情精品久久久久久久变态| 欧美一区2区视频在线观看| 美国三级日本三级久久99| 午夜精品一区二区三区电影天堂 | 国产日韩欧美一区在线| 亚洲人体偷拍| 在线观看精品一区| 亚洲一区二区三区在线观看视频| 亚洲电影有码| 欧美主播一区二区三区美女 久久精品人| 亚洲激情电影在线| 欧美一站二站| 欧美在线播放高清精品| 欧美日韩国产综合网| 男人插女人欧美| 韩国精品主播一区二区在线观看| 在线视频亚洲一区| 一区二区三区欧美视频| 蜜臀av一级做a爰片久久| 久久一区二区三区av| 久久久精品tv| 久久婷婷国产综合国色天香| 国产精品久久久久免费a∨| 亚洲国产欧洲综合997久久| 伊人久久噜噜噜躁狠狠躁| 欧美在线免费| 久久久久欧美精品| 国产亚洲激情在线| 羞羞漫画18久久大片| 欧美一区午夜视频在线观看| 国产精品乱码妇女bbbb| 亚洲在线电影| 欧美专区一区二区三区| 国产无一区二区| 欧美一区影院| 麻豆精品国产91久久久久久| 亚洲高清免费视频| 欧美69视频| 亚洲黄色成人| 国产精品99久久久久久人| 国产精品啊v在线| 亚洲永久免费视频| 久久综合给合久久狠狠色 | 日韩五码在线| 亚洲一区999| 国产精品网站视频| 欧美一区二区日韩一区二区| 久久综合久久综合久久| 亚洲电影av| 欧美日韩精品二区| 亚洲欧洲av一区二区三区久久| 久久精品视频在线播放| 亚洲成人在线观看视频| 欧美激情一二三区| 中国日韩欧美久久久久久久久| 久久成人免费网| 1024日韩| 国产精品久久久久久久久久久久久久| 一区二区三区视频在线| 久久精品在线| 夜夜嗨av一区二区三区免费区| 国产精品美女视频网站| 久久久xxx| 一本色道久久综合| 久久三级视频| 亚洲视频网在线直播| 韩日精品中文字幕| 欧美日韩99| 欧美在线视屏| 亚洲少妇中出一区| 欧美成在线观看| 亚洲欧美国产精品va在线观看| 狠狠色丁香婷综合久久| 欧美成人免费网站| 亚洲欧美另类在线观看| 欧美激情综合色| 欧美在线日韩在线| aa成人免费视频| 在线精品一区| 国产精品呻吟| 欧美日本在线| 美女视频网站黄色亚洲| 性欧美暴力猛交69hd| 亚洲人永久免费| 久热精品视频在线| 午夜欧美大尺度福利影院在线看| 亚洲精品国偷自产在线99热| 国内精品久久久久影院 日本资源| 欧美另类极品videosbest最新版本| 亚洲欧美日韩天堂一区二区| 亚洲午夜性刺激影院| 日韩亚洲综合在线| 亚洲国产高清一区| 狠狠爱www人成狠狠爱综合网|