欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

windows mobile下的wininet的使用

程序员文章站 2023-12-30 19:00:22
...

  同步的就不说了,网上和MSDN上有代码。

     对于异步的处理,贴上源代码。参考MSDN上面的代码和网上一些前辈的代码。

     加上了我自己的一些理解和注释,方便后来学习者学习或直接使用。

 

HttpSession.h

 


1 #pragma once
2
3 #include <vector>
4 #include <WinInet.h>
5
6  #define MAXBUFFERSIZE 65535
7
8  #define T_ACCEPT_ENCODING "Accept-Encoding"
9  #define T_CLIENTAGENT "Client-Agent"
10 #define T_CALLINGLINEID "x-up-calling-line-id"
11 #define T_APIVERSION "APIVersion"
12 #define T_USERID "user-id"
13 #define T_ACTION "nAction"
14 #define T_COOKIE "Cookie"
15 #define T_CONTENTTYPE "Content-Type"
16 #define T_CLIENTTYPE "X-ClientType"
17 #define T_CONTENTLEN "Content-Length"
18 #define T_HOST "Host"
19
20 #ifndef FREEIF
21 #define FREEIF(p) {if (p) {delete (p); (p) = NULL;}}
22 #endif
23
24 #ifndef FREEARRAYIF
25 #define FREEARRAYIF(p) {if (p) { delete[] p; (p) = NULL; }}
26 #endif
27
28 void AsyncInternetCallback2(HINTERNET hInternet,
29 DWORD dwContext,
30 DWORD dwInternetStatus,
31 LPVOID lpStatusInfo,
32 DWORD dwStatusInfoLen);
33
34 class CHttpSession
35 {
36 public:
37 CHttpSession();
38 ~CHttpSession();
39
40 public:
41 //添加请求头字符串
42 bool SetHeadValue( const char* aKey, const char* aValue );
43
44 bool SetServer( const char* aServer );
45
46 //URL不包含服务器IP和端口号
47 bool SetRequestUrl( const char* aUrl );
48
49 bool SetPort( int aPort );
50
51 //设置请求数据,仅用于POST请求,GET请求无需使用
52 bool SetRequestData( const char* aData );
53
54 inline const char* GetRecvHead();
55
56 //获取返回的数据体
57 inline const char* GetRecvieData( );
58
59 //获取返回数据的长度
60 inline DWORD GetReceivedDataLen();
61
62 //获取返回码
63 DWORD GetRetCode();
64
65 //获取返回数据头中的字段的值
66 const char* GetRetHeadValue( char* aKey );
67
68 //调用doRequest之前,需要将所有数据都准备好
69 bool DoRequest();
70
71 protected:
72 BOOL RetrievingHeaders(HINTERNET hHttp);
73
74 protected:
75 std::vector<char*> m_vtRequestHead; //请求消息头的字符串
76 char* m_pRequestBody; //请求的消息体
77 DWORD m_dwRequestBodyLen; //请求消息体的长度
78
79 char* m_pHost; //服务器地址
80 int m_pPort; //端口
81 char* m_pRequestUrl; //请求URL地址
82
83 char* m_pRecvHead; //接收到的数据头
84 char* m_pRecvBuf; //接收的缓存
85 DWORD m_dwRecvBodySize; //收到数据的总大小
86 DWORD m_dwMaxBuf; //接收数据缓存的总容器大小
87 DWORD m_dwStartPos; //当前缓存的偏移,已存放在缓存中的数据长度
88 };
89

 

HttpSession.cpp:

 

 

#include "stdafx.h"
#include "HttpSession.h"
#include "Util.h"
#include <wininet.h>
#pragma comment(lib, "Wininet.lib")

HINTERNET hInstance;
HINTERNET hConnect;
HINTERNET hRequest;

HANDLE hConnectedEvent;
HANDLE hRequestOpenedEvent;
HANDLE hRequestCompleteEvent;

BOOL bAllDone ;

extern const char * lpszServer;
extern const char * lpszUrl;

#define CONNECTION_CONTEXT 1
#define REQUEST_CONTEXT    2

#define MAX_BODY_SIZE      10*1024

CHttpSession::CHttpSession()
:m_pRequestBody(NULL),m_pHost(NULL), m_pRequestUrl( NULL ),m_pRecvBuf(NULL),m_pRecvHead(NULL)
,m_dwRecvBodySize(0), m_dwMaxBuf(0) ,m_dwStartPos(0),m_dwRequestBodyLen(0)
{
	hConnectedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	hRequestOpenedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	hRequestCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
}

CHttpSession::~CHttpSession()
{
	FREEARRAYIF( m_pRequestBody );
	FREEARRAYIF( m_pHost );
	FREEARRAYIF( m_pRequestUrl );
	FREEARRAYIF( m_pRecvBuf );
	FREEARRAYIF( m_pRecvHead );
}

bool CHttpSession::SetHeadValue( const char* aKey, const char* aValue )
{
	if ( !aKey )
		return false;

	char* buf = new char[256];
	memset( buf, 0, 256 );
	sprintf( buf, "%s: %s\r\n", aKey, aValue );

	m_vtRequestHead.push_back( buf );
	return true;
}

bool CHttpSession::SetRequestData( const char* aData )
{
	if( !aData )
		return false;
	
	m_pRequestBody = new char[strlen( aData ) + 1];
	memset( m_pRequestBody, 0, strlen( aData ) + 1 );
	memcpy( m_pRequestBody, aData, strlen( aData ) );

	return true;
}

bool CHttpSession::SetServer( const char* aServer )
{
	if( !aServer )
		return false;

	m_pHost = new char[strlen( aServer ) + 1 ];
	memset( m_pHost, 0, strlen( aServer ) + 1 );
	memcpy( m_pHost, aServer, strlen( aServer ) );

	return true;
}

bool CHttpSession::SetRequestUrl( const char* aUrl )
{
	if( !aUrl )
		return false;

	m_pRequestUrl = new char[strlen( aUrl ) + 1 ] ;
	memset( m_pRequestUrl, 0, strlen( aUrl ) + 1 );
	memcpy( m_pRequestUrl, aUrl, strlen( aUrl ) );

	return true;

}

bool CHttpSession::SetPort( int aPort )
{
	if ( aPort < 0 )
	{
		return false;
	}
	m_pPort = aPort;
	return true;
}

bool CHttpSession::DoRequest()
{
	//异步
	hInstance = InternetOpenA( "TYYD_Mobile_6_0_240_320_E806_C_GG_1_0_0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC); // ASYNC Flag

	if( !hInstance ) //有些手机用上面的参数访问不了Internet
		hInstance=InternetOpenA("TYYD_Mobile_6_0_240_320_E806_C_GG_1_0_0",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,INTERNET_FLAG_ASYNC);
	if ( !hInstance )
	{
		TraceLog( L"InternetOpen failed, error : %d \r\n",GetLastError() );
		return false;
	}
	TraceLog( L"InternetOpen suceess :%d \r\n",GetLastError() );

	// Setup callback function
	if (InternetSetStatusCallbackA(hInstance,(INTERNET_STATUS_CALLBACK)&AsyncInternetCallback2) == INTERNET_INVALID_STATUS_CALLBACK)
	{
		TraceLog( L"InternetSetStatusCallback failed, error : %d \r\n",GetLastError() );
		return false;
	}
	TraceLog( L"InternetSetStatusCallback suceess :%d \r\n",GetLastError() );

	// First call that will actually complete asynchronously even
	// though there is no network traffic
	hConnect = InternetConnectA(hInstance,m_pHost, m_pPort,NULL,NULL,INTERNET_SERVICE_HTTP,0,1); // Connection handle's Context

	if (hConnect == NULL)
	{
		TraceLog( L"hConnect == NULL, errno = %d \r\n ",GetLastError() );

		if (GetLastError() != ERROR_IO_PENDING)
		{
			TraceLog( L"InternetConnect failed, error %d  ",GetLastError() );

			return false; 
		}
	}
	// Wait until we get the connection handle
	WaitForSingleObject(hConnectedEvent, INFINITE);
	TraceLog( L"Ready To openRequest \r\n");

	char* pVerb = !m_pRequestBody ? "GET" : " POST" ;

	const char * lpszUrl = "/portalapi/imagedownload?key=1000002845492.jpg&type=content";

	// Open the request
	hRequest = HttpOpenRequestA(hConnect, 
		pVerb, 
		m_pRequestUrl,
		NULL,         // HTTP version ,If this parameter is NULL, the function uses HTTP/1.1 as the version
		NULL,         // Reference
		NULL,// A pointer to a null-terminated array of strings that indicates media types accepted by the client.
		INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE,
		2);  // Request handle's context 

	if (hRequest == NULL)
	{
		if (GetLastError() != ERROR_IO_PENDING)
		{
			TraceLog( L"HttpOpenRequest failed, error = %d \r\n", GetLastError() );
			return false;
		}
	}

	// Wait until we get the request handle
	WaitForSingleObject(hRequestOpenedEvent, INFINITE);

	TraceLog( L"HttpOpenRequest Sucess\r\n" );

	//Add Request HeadInfo
	for( int i = 0 ; i < m_vtRequestHead.size(); i++ )
	{
		char* pItem = m_vtRequestHead[i];
		HttpAddRequestHeadersA(hRequest, pItem, -1, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE );
	}

	int nRequestBody = !m_pRequestBody ? 0 : strlen( m_pRequestBody );

	// Sends the specified request to the HTTP server.
	if (!HttpSendRequestA(hRequest, 
		NULL,              // Pointer to a null-terminated string that contains the additional headers to be appended to the request. 
		0,                 // Size of the additional headers
		m_pRequestBody,    // Pointer to a buffer containing any optional data to be sent immediately after the request headers.
		m_dwRequestBodyLen ))                // Size of the optional data, in bytes.
	{
		if (GetLastError() != ERROR_IO_PENDING)
		{
			TraceLog( L"HttpSendRequest failed, error = %d \r\n", GetLastError() );

			return false;
		}
	}

	TraceLog( L"HttpSendRequest Sucess \r\n" );

	WaitForSingleObject(hRequestCompleteEvent, INFINITE);

	TraceLog( L"------------------- Read the response -------------------\r\n" );
	
	//获取响应数据包头
	RetrievingHeaders( hRequest );

	DWORD dwLen = 0;

	InternetQueryDataAvailable(hRequest,&dwLen,0,0);

	char* lpReadBuff = new char[MAX_BODY_SIZE];	
	do
	{
		memset(lpReadBuff, 0, MAX_BODY_SIZE);
		INTERNET_BUFFERSA InetBuff;
		FillMemory(&InetBuff, sizeof(InetBuff), 0);
		InetBuff.dwStructSize = sizeof(InetBuff);
		InetBuff.lpvBuffer = (LPVOID)lpReadBuff;
		InetBuff.dwBufferLength = MAX_BODY_SIZE - 1;

		TraceLog( L"Calling InternetReadFileExA \r\n" );

		if ( !InternetReadFileExA(hRequest,&InetBuff,IRF_ASYNC, 2) )
		{
			if (GetLastError() == ERROR_IO_PENDING)
			{
				TraceLog( L"Waiting for InternetReadFileEx to complete \r\n" );
				WaitForSingleObject(hRequestCompleteEvent, INFINITE);
			}
			else
			{
				TraceLog( L"InternetReadFileEx failed, error :%d \r\n", GetLastError() );
				return false;
			}
		}
		TraceLog( L"InternetReadFileEx success! ReadBufLen = %d \r\n", InetBuff.dwBufferLength );


		if (InetBuff.dwBufferLength == 0) 
		{
			TraceLog( L"RecvBuf Complete \r\n");
			bAllDone = TRUE;

			FILE *file;
			file = fopen( "\\a1.jpg", "wb" );
			int nwrite;
			if ( file )
			{
				nwrite = fwrite( m_pRecvBuf, 1, m_dwRecvBodySize, file);
			}
			fclose(file);
		}
		else
		{
			m_dwRecvBodySize += InetBuff.dwBufferLength;

			if ( !m_pRecvBuf )
			{
				m_pRecvBuf = new char[MAX_BODY_SIZE];
				memset( m_pRecvBuf, 0, MAX_BODY_SIZE );
				m_dwMaxBuf = MAX_BODY_SIZE;
			}

			//剩余空间不足,重新分配空间
			if ( m_dwMaxBuf - m_dwStartPos < InetBuff.dwBufferLength + 1)
			{
				TraceLog( L" Memspace is not enough!" );
				char* pTempBuf = m_pRecvBuf;
				m_pRecvBuf = new char[m_dwMaxBuf + MAX_BODY_SIZE];
				memset( m_pRecvBuf, 0, m_dwMaxBuf + MAX_BODY_SIZE);
				m_dwMaxBuf = m_dwMaxBuf + MAX_BODY_SIZE;
				memcpy( m_pRecvBuf, pTempBuf, m_dwStartPos);
				delete[] pTempBuf;
				pTempBuf = NULL;
			}

			TraceLog( L" Memspace is enough!" );
			memcpy( m_pRecvBuf + m_dwStartPos, lpReadBuff, InetBuff.dwBufferLength );
			TraceLog( L"InternetReadFileEx startPos = %d, curRecvLen = %d, totalSize = %d! \r\n", m_dwStartPos, InetBuff.dwBufferLength , m_dwRecvBodySize);
			m_dwStartPos += InetBuff.dwBufferLength;
		}

	} while (bAllDone == FALSE);

	FREEARRAYIF( lpReadBuff );
	return true;
}

BOOL CHttpSession::RetrievingHeaders(HINTERNET hHttp)
{
	//LPVOID lpOutBuffer=NULL;
	DWORD dwSize = 0;
	FREEARRAYIF( m_pRecvHead );

retry:

	// This call will fail on the first pass, because no buffer is allocated.
	if(!HttpQueryInfo(
		hHttp,
		HTTP_QUERY_RAW_HEADERS_CRLF,
		(LPVOID)m_pRecvHead,
		&dwSize,
		NULL))
	{ 
		if (GetLastError()==ERROR_HTTP_HEADER_NOT_FOUND)
		{
			TraceLog( L"HttpQueryInfo error : ERROR_HTTP_HEADER_NOT_FOUND \r\n" );
			// Code to handle the case where the header isn't available.
			return TRUE;
		}		
		else
		{
			// Check for an insufficient buffer.
			if ( GetLastError()==ERROR_INSUFFICIENT_BUFFER )
			{
				TraceLog( L"HttpQueryInfo error : ERROR_HTTP_HEADER_NOT_FOUND \r\n" );
				m_pRecvHead = new char[dwSize];

				// Retry the call.
				goto retry;				
			}		
			else
			{
				TraceLog( L"HttpQueryInfo error : %d \r\n", GetLastError() );

				// Error handling code.
				if (m_pRecvHead)
				{
					delete [] m_pRecvHead;
				}
				return FALSE;
			}		
		}		
	}	

	TraceLog( L"HttpQueryInfo sucess lpOutBuffer = %s\r\n", m_pRecvHead);

	return TRUE;
}

DWORD CHttpSession::GetRecvieData()
{
	return m_pRecvBuf;
}

const char* CHttpSession::GetRecvHead()
{
	return m_pRecvHead;
}

DWORD CHttpSession::GetReceivedDataLen()
{
	return m_dwRequestBodyLen;
}

void AsyncInternetCallback2(HINTERNET hInternet,
										  DWORD dwContext,
										  DWORD dwInternetStatus,
										  LPVOID lpStatusInfo,
										  DWORD dwStatusInfoLen)
{
	TraceLog( L"dwContext = %d, dwInternetStatus = %d \r\n", dwContext, dwInternetStatus );

	switch(dwContext)
	{
	case 1: // Connection handle
		if (dwInternetStatus == INTERNET_STATUS_HANDLE_CREATED)
		{
			INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
			hConnect = (HINTERNET)pRes->dwResult;
			TraceLog( L"Connect handle created \r\n");
			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;

				TraceLog( L"Request handle created \r\n");

				SetEvent(hRequestOpenedEvent);
			}
			break;
		case INTERNET_STATUS_REQUEST_SENT:
			{
				DWORD *lpBytesSent = (DWORD*)lpStatusInfo;
				TraceLog( L"Bytes Sent:%d \r\n", lpBytesSent );
			}
			break;
		case INTERNET_STATUS_REQUEST_COMPLETE:
			{
				INTERNET_ASYNC_RESULT *pAsyncRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
				TraceLog( L"Function call finished, dwResult: %d, dwError:  \r\n", pAsyncRes->dwResult, pAsyncRes->dwError);

				SetEvent(hRequestCompleteEvent);
			}
			break;
		case INTERNET_STATUS_RECEIVING_RESPONSE:
			TraceLog( L"Receiving Response \r\n" );
			break;
		case INTERNET_STATUS_RESPONSE_RECEIVED:
			{
				DWORD *dwBytesReceived = (DWORD*)lpStatusInfo;
				if (*dwBytesReceived == 0)
					bAllDone = TRUE;
				TraceLog( L"Receiving %d \r\n", dwBytesReceived);
			}
		}

		break;
	default:break;
	}
}

测试环境:vs2008 + windows mobile 2003
测试代码:
	CHttpSession* pSession = new CHttpSession();

	pSession->SetServer( lpszServer );
	pSession->SetPort( 8080 );
	pSession->SetRequestUrl( lpszUrl );
	pSession->SetRequestData( NULL );

	pSession->SetHeadValue( T_ACCEPT_ENCODING, "gzip" );
	pSession->SetHeadValue( T_CLIENTAGENT, "TYYD_Mobile_6_0_240_320_E806_C_GG_1_0_0" );
	pSession->SetHeadValue( T_CALLINGLINEID, "18912345677" );
	pSession->SetHeadValue( T_APIVERSION, "1.0.0" );
	pSession->SetHeadValue( T_CONTENTTYPE, "application/xml" );
	pSession->SetHeadValue( T_CLIENTTYPE, "1");
	pSession->SetHeadValue( T_USERID, "" );
	pSession->SetHeadValue( T_COOKIE, "" );
	pSession->SetHeadValue( T_ACTION, "" );	

	pSession->DoRequest();

转载于:https://www.cnblogs.com/deagle/articles/1911706.html

上一篇:

下一篇: