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

隨筆 - 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>
            一本一本a久久| 国产日韩在线播放| 一本一本大道香蕉久在线精品| 久久综合色影院| 久久精品国产在热久久| 久久久xxx| 久久精品一区中文字幕| 欧美高清在线播放| 日韩一区二区精品| 亚洲欧美日韩国产精品 | 久久免费午夜影院| 欧美一级在线亚洲天堂| 西西人体一区二区| 亚洲国产mv| 亚洲性夜色噜噜噜7777| 午夜欧美视频| 欧美激情视频免费观看| 国产日韩欧美成人| 99天天综合性| 久久国内精品自在自线400部| 亚洲二区精品| 久久精品色图| 国产综合色产| 久久精品国亚洲| 午夜精品久久久久久久99黑人| 欧美日韩国产成人高清视频| 亚洲国产色一区| 久久久最新网址| 亚洲一级二级在线| 欧美三级在线| 午夜精品区一区二区三| aaa亚洲精品一二三区| 欧美理论在线播放| 亚洲图片欧美午夜| 一本久久精品一区二区| 欧美日韩综合一区| 欧美一区亚洲二区| 久久本道综合色狠狠五月| 国产婷婷色一区二区三区四区| 亚洲欧美日韩综合aⅴ视频| 中文在线一区| 黄色av日韩| 亚洲电影一级黄| 欧美日韩一区在线播放| 久久高清一区| 免费精品视频| 噜噜噜91成人网| 亚洲精品一区二| 午夜天堂精品久久久久| 亚洲黄页一区| 午夜精品久久久久影视| 亚洲精品国产精品国自产观看浪潮| 亚洲精品激情| 亚洲国产日韩欧美一区二区三区| 99视频精品全国免费| 在线精品在线| 欧美一二区视频| 亚洲视频精选| 欧美精品18| 欧美福利一区| 狠狠色香婷婷久久亚洲精品| 在线亚洲成人| 一区二区欧美亚洲| 欧美理论视频| 夜夜精品视频一区二区| 日韩一级黄色大片| 欧美日韩成人在线观看| 老牛影视一区二区三区| 国产在线播精品第三| 亚洲欧美色一区| 久久成人免费网| 国产在线观看一区| 久久99在线观看| 久久一区二区精品| 极品av少妇一区二区| 久久久精品动漫| 久久久久国产精品厨房| 国产欧美一区二区精品忘忧草| 欧美激情91| 一区二区免费看| 国产精品欧美激情| 亚洲欧美日韩一区二区三区在线观看 | 欧美在线看片a免费观看| 欧美一区日本一区韩国一区| 国产精品中文字幕欧美| 亚洲欧美制服另类日韩| 先锋影音网一区二区| 国产欧美一区二区三区久久| 久久嫩草精品久久久久| 欧美激情一区二区| 欧美一二三区精品| 精品成人久久| 欧美老女人xx| 欧美一区在线看| 欧美激情在线观看| 久久高清福利视频| 99视频超级精品| 在线观看91精品国产麻豆| 美女999久久久精品视频| 一区二区三区视频在线观看| 久久免费黄色| 亚洲欧美日韩电影| 亚洲国产精品一区二区三区| 欧美肥婆bbw| 久热精品在线视频| 免费观看亚洲视频大全| 欧美一区二区精美| 国产一区成人| 国产精品日韩欧美一区二区三区| 欧美电影在线| 欧美大片va欧美在线播放| 久久精品国产综合精品| 性久久久久久| 新狼窝色av性久久久久久| 亚洲一区二区三区中文字幕| 亚洲看片一区| 日韩系列在线| 亚洲精品中文字幕女同| 亚洲精品九九| 在线视频精品一区| 亚洲制服av| 久久人人97超碰国产公开结果| 欧美一区免费| 亚洲第一黄色网| 亚洲日韩欧美视频一区| 欧美激情视频网站| 日韩一级精品| 欧美一级在线播放| 欧美成人国产| 国产精品区一区| 亚洲高清一二三区| 亚洲性感美女99在线| 久久综合中文色婷婷| 亚洲精品日本| 亚洲影院污污.| 久久亚洲国产精品一区二区| 欧美韩日视频| 韩国欧美一区| 日韩午夜电影| 久久亚洲综合| 亚洲先锋成人| 欧美少妇一区二区| 亚洲福利小视频| 国产日本欧美一区二区三区| 欧美日韩一区视频| 欧美中文字幕在线播放| 欧美成年人网站| 欧美激情一区在线| 午夜一级久久| 久久亚洲综合| 欧美日韩国产综合视频在线观看中文 | 久久天天狠狠| 亚洲天堂免费观看| 国产精品久久久久久超碰| 欧美一区永久视频免费观看| 国产精品久久国产三级国电话系列 | 樱花yy私人影院亚洲| 久久久久久久999| 欧美精品日韩综合在线| 亚洲欧美第一页| 久久久久久婷| 亚洲一区二区三区精品视频| 一本一本a久久| 精品成人一区二区| 一道本一区二区| 亚洲激情视频| 欧美一区二区三区啪啪| 9l国产精品久久久久麻豆| 亚洲免费视频一区二区| 亚洲精品日韩在线观看| 欧美一级大片在线观看| 99国产精品国产精品久久| 久久精品一区蜜桃臀影院| 亚洲伊人色欲综合网| 欧美黄色一区二区| 欧美激情亚洲精品| 亚洲国产精品久久人人爱蜜臀 | 欧美福利视频在线观看| 久久综合精品国产一区二区三区| 国产一区二区三区的电影 | 亚洲欧美影院| 国产精品一区二区三区免费观看 | 午夜视频久久久久久| 欧美日韩在线视频一区| 亚洲精品乱码| 亚洲午夜视频在线| 欧美日韩调教| 亚洲一区二区三区视频| 性色av一区二区三区红粉影视| 欧美午夜精品理论片a级大开眼界 欧美午夜精品理论片a级按摩 | 亚洲美女区一区| 欧美精品在线视频观看| 免费人成网站在线观看欧美高清 | 小嫩嫩精品导航| 午夜久久99| 激情综合久久| 欧美日韩午夜在线| 久久国产精品一区二区三区| 免费成人在线观看视频| 夜夜嗨av一区二区三区免费区|