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

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

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 郭天文 閱讀(2472) 評論(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>
            久久黄色网页| 欧美一区2区三区4区公司二百 | 亚洲毛片在线观看.| 久久夜色撩人精品| 久久精品免费看| 国内久久精品视频| 欧美freesex8一10精品| 免费在线观看一区二区| 亚洲欧洲一区二区三区久久| 欧美大尺度在线| 欧美精品1区| 亚洲自拍高清| 欧美一级一区| 亚洲经典自拍| 99热精品在线观看| 国产精品欧美久久| 久久在线免费观看| 欧美第十八页| 欧美诱惑福利视频| 蜜臀av国产精品久久久久| 亚洲三级电影全部在线观看高清| 亚洲九九精品| 国产一区二区久久精品| 免费91麻豆精品国产自产在线观看| 免费在线观看成人av| 亚洲欧美一区二区激情| 久久久久久有精品国产| 在线亚洲一区观看| 新67194成人永久网站| 亚洲国产综合在线看不卡| 国产精品99久久久久久久vr| 激情综合激情| 亚洲天堂免费观看| 亚洲电影有码| 午夜激情久久久| 99在线视频精品| 久久精品国产精品| 亚洲影视在线| 欧美激情四色 | 亚洲美女在线一区| 亚洲免费在线精品一区| 亚洲日本一区二区| 欧美专区亚洲专区| 亚洲一卡久久| 欧美肥婆在线| 久久免费国产精品1| 欧美色视频在线| 欧美黄色成人网| 国产婷婷色一区二区三区四区| 亚洲人成毛片在线播放| 国产精品网站在线| 日韩亚洲视频| 亚洲人午夜精品| 久久永久免费| 久久亚洲一区二区三区四区| 国产精品久久97| 99国产精品私拍| 一本色道88久久加勒比精品| 美国三级日本三级久久99| 久久激情五月激情| 国产欧美韩日| 亚洲淫片在线视频| 亚洲女女女同性video| 欧美日韩精品三区| 亚洲精品一级| 一本色道久久加勒比88综合| 欧美成人免费在线观看| 欧美国产激情| 99精品久久免费看蜜臀剧情介绍| 久久久亚洲国产美女国产盗摄| 久久精品免费| 国产专区欧美专区| 久久免费视频网站| 猛男gaygay欧美视频| 在线成人免费观看| 久久一本综合频道| 亚洲第一在线综合网站| 亚洲精品久久久久久久久久久久久| 久久久无码精品亚洲日韩按摩| 久久人体大胆视频| 1000部精品久久久久久久久| 久久人人爽爽爽人久久久| 欧美福利一区二区三区| 亚洲精品日韩在线| 欧美三级视频在线观看| 亚洲一区精品在线| 可以看av的网站久久看| 亚洲清纯自拍| 欧美日韩在线播放一区二区| 一区二区三区高清视频在线观看| 午夜一区二区三区不卡视频| 国产一区二区三区精品欧美日韩一区二区三区 | 一区精品久久| 欧美成人精品一区二区| 中文在线不卡| 久久女同精品一区二区| 亚洲精品视频一区二区三区| 欧美天天在线| 欧美一级久久久| 亚洲成人在线网站| 亚洲国产婷婷| 在线视频欧美日韩| 国产欧美一区二区三区国产幕精品| 久久成人免费网| 最新69国产成人精品视频免费| 亚洲影院高清在线| 亚洲国产精品久久久久婷婷884 | 狠狠色综合播放一区二区| 免费欧美日韩| 亚洲女人天堂av| 亚洲激情av在线| 小黄鸭精品aⅴ导航网站入口| 在线视频国产日韩| 国产精品亚洲综合| 欧美电影美腿模特1979在线看| 亚洲一区在线观看免费观看电影高清| 免费成人黄色av| 午夜精品一区二区三区电影天堂| 在线不卡视频| 国产午夜精品理论片a级探花| 免费在线亚洲欧美| 欧美在线啊v| 中国成人亚色综合网站| 欧美国产日韩在线| 久久久久www| 亚洲一区二区在线免费观看| 亚洲国产另类精品专区| 国产一区二区高清视频| 欧美日韩精品一区二区在线播放 | 久久亚洲国产精品日日av夜夜| 一本一道久久综合狠狠老精东影业 | 久久国产精品久久w女人spa| 一区二区三区久久网| 1000部国产精品成人观看| 国产主播在线一区| 国产日本亚洲高清| 国产精品久久夜| 欧美三区在线观看| 欧美精品系列| 欧美国产日产韩国视频| 麻豆av福利av久久av| 久久免费精品视频| 久久综合九色99| 欧美在线视频免费播放| 亚洲欧美精品suv| 亚洲欧美日韩一区二区在线 | 美女网站在线免费欧美精品| 久久精品国产91精品亚洲| 久久se精品一区精品二区| 午夜国产精品视频| 午夜国产一区| 欧美一区二区三区四区视频| 性色av一区二区三区| 亚洲欧美中文日韩在线| 羞羞漫画18久久大片| 欧美一区三区三区高中清蜜桃| 午夜精品久久| 久久国产精品久久久| 久久久成人精品| 久久伊人亚洲| 欧美黄色免费网站| 亚洲精品小视频| 亚洲一区二区三区免费观看| 亚洲欧美日韩一区在线观看| 先锋影音网一区二区| 久久久精品久久久久| 你懂的视频欧美| 欧美日韩国产另类不卡| 国产精品爱啪在线线免费观看| 国产精品日日摸夜夜添夜夜av| 国产视频一区二区在线观看 | 国产精品久久久久久久久久尿| 国产精品视频999| 精品99一区二区三区| 亚洲精品一区二区三区av| 一区二区三区毛片| 羞羞色国产精品| 欧美va天堂| 中文av一区特黄| 久久久激情视频| 欧美日韩精品在线视频| 国产精品一区2区| 亚洲高清视频在线| 亚洲欧美综合精品久久成人| 久久一区二区三区四区| 亚洲肉体裸体xxxx137| 亚洲欧美日韩在线播放| 免费成人美女女| 国产精品午夜久久| 99热精品在线观看| 欧美亚洲视频在线观看| 欧美激情视频一区二区三区不卡| 一区二区欧美在线| 久久人体大胆视频| 国产欧美日韩不卡免费| 日韩一区二区电影网| 两个人的视频www国产精品| 99视频日韩| 欧美1级日本1级| 韩国成人理伦片免费播放|