Using WinInet HTTP functions in Full Asynchronous Mode

Detail

http://www.codeproject.com/Articles/822/Using-WinInet-HTTP-functions-in-Full-Asynchronous

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 useInternetReadFile since it is a synchronous function. You must loop on InternetReadFileEx while theib.dwBufferLength is not 0. Before each iteration you must adjust the lpvBuffer pointer and reset thedwBufferLength 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 inmy guestbook and buy me a license of my shareware.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值