进行windows mobile网络应用开发,必须要了解如何建立gprs等网络连接。windows为我们提供了conn manager来完成这类功能。
首先:WM5 SDK中的示例cmhelper基本包含了conn mgr的用法。默认安装的示例代码的路径是:C:/Program Files/Windows CE Tools/wce500/Windows Mobile 5.0 Pocket PC SDK/Samples/CPP/Mfc/CMHELPER/cmhelper.sln
一般来说,我们要使用连接管理器的步骤如下:
1、ConnMgrApiReadyEvent
看看MSDN怎么说:This function provides a way for applications to check whether Connection Manager is ready. The calling application is responsible for calling the Windows CE CloseHandle function for the returned event.
也就是说,使用连接管理器这前,要通过这个API确认连接管理器的确可用。
调用代码片段如下:
HANDLE hConnMgr = ConnMgrApiReadyEvent();
BOOL bAvailbale = FALSE;
DWORD dwResult = ::WaitForSingleObject( hConnMgr, 2000 );
if ( dwResult == WAIT_OBJECT_0 )
{
bAvailbale = TRUE;
}
// 关闭
if ( hConnMgr ) CloseHandle( hConnMgr );
2、ConnMgrMapURL
连接管理器通过这个API,帮你找出一个合适的连接点。
使用方法是,传入一下你准备要访问的URL,你将会得到一个可以访问到这个URL的连接点的GUID
代码片段如下:
GUID connGuid;
int nIndex = 0;
HRESULT hResult = ConnMgrMapURL ( _T("http://www.g.cn"), &connGuid, (DWORD*)&nIndex );
if (FAILED(hResult) )
{
nIndex = -1;
memset ( &connGuid, 0, sizeof(GUID) );
DWORD dwLastError = GetLastError ();
}
得到连接点的GUID后,就可以请求连接管理器建立连接了。
连接管理器建立连接有同步和异步两种方式。异步方式的使用参见cmhelper示例
下面介绍同步的使用方法。
3、ConnMgrEstablishConnectionSync
代码片断如下:
// 初始化连接结构
CONNMGR_CONNECTIONINFO ConnInfo;
ZeroMemory(&ConnInfo, sizeof(ConnInfo));
ConnInfo.cbSize = sizeof(ConnInfo);
ConnInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET;
if (1 == useProxy)
{// 代理
ConnInfo.dwFlags = CONNMGR_FLAG_PROXY_HTTP;
}
else
{
ConnInfo.dwFlags = 0;
}
ConnInfo.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;
ConnInfo.guidDestNet = apGuid;
ConnInfo.bExclusive = FALSE;
ConnInfo.bDisabled = FALSE;
DWORD dwStatus = 0;
HRESULT hResult = ConnMgrEstablishConnectionSync(&ConnInfo, &m_hConn, 100*1000, &dwStatus );
if(FAILED(hResult))
{
m_hConn = NULL;
logerror(("CenoConnMgr::conn 拨号失败 connstate is:%d", dwStatus));
return -1;//失败
}
else
{
logdebug(("CenoConnMgr::conn 拨号成功。"));
return 0;//成功
}
到这里已经完成了连接GPRS连接的操作,接下来就可以使用socket或者winInet来进行数据的收发了。
但是在使用wap连接时,要涉及wap连接代理设置的问题。这时可以使用ConnMgrProviderMessage API来取得当前连接点的代理设置。这个就可以通过代理顺利地访问网络了。
4、ConnMgrProviderMessage
代码片段如下:
DWORD dwIndex = 0;
PROXY_CONFIG m_proxy = { 0};
HRESULT hr = ConnMgrProviderMessage(m_hConn,
&IID_ConnPrv_IProxyExtension,
&dwIndex, 0, 0, (PBYTE)&m_proxy, sizeof(m_proxy));
if (hr == S_OK)
{
logdebug(("CenoConnMgr::GetProxyServer dwIndex: %d", dwIndex));
logdebug(("CenoConnMgr::GetProxyServer 代理服务器为: %s", U2A(m_proxy.szProxyServer).ToChar()));
}
else
{
return NULL;
}
这里的m_hConn就是刚才建立连接后得到了连接handle。
代理设置应用在InternetOpen API中。如下:
InternetOpen(_T("XXXXXXXXXX"),
INTERNET_OPEN_TYPE_PROXY,
m_proxy->szProxyServer,
NULL,
INTERNET_FLAG_ASYNC); // ASYNC Flag
到这里,连接管理器的使用介绍完毕。
================================================
不过要用好连接管理器,还有很多事情要做的。一个完善的网络应用程序,不仅要考虑建立连接,还要考虑释放连接。甚至在系统中没有可用的连接点设置时,要新建一个连接点。
下面我们接着介绍。
释放连接
可以使用ConnMgrReleaseConnection,但是这个API并不会立即生效。它只是向连接管理器的调试器请求断开连接,如果系统中有其他的程序也在使用这个连接点访问网络,那么它会等到所有使用它的进程使用完毕并且还要再等一段时间(cache time)才真正断开连接。
所以如果要马上断开连接,还要找其他的办法。
这里有一个做法,它能够生效,但是却有可能会产生负作用。当然我现在还没有见识到。
int index; // An integer index
DWORD dwError, dwRasConnSize, dwNumConnections; // Number of connections found
RASCONN RasConn[20]; // Buffer for connection state data,Assume the maximum number of entries is 20.
// Assume no more than 20 connections.
RasConn[0].dwSize = sizeof(RASCONN);
dwRasConnSize = 20 * sizeof (RASCONN);
// Find all connections.
if (dwError = RasEnumConnections (RasConn, &dwRasConnSize,&dwNumConnections))
{
return;
}
for (int i = 0; i < dwRasConnSize; i++)
{
RasHangUp(RasConn[i].hrasconn);
}
建立连接点
使用DMProcessConfigXML
const wchar_t guid_of_new_cm_ap[] = L"{84C79B75-DB1C-9C47-5220-0F665CBC08C6}";
const wchar_t NEW_AP_OF_CHINA_MOBILE[] =
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
L"
DMProcessConfigXML(NEW_AP_OF_CHINA_MOBILE, CFGFLAG_PROCESS, &pszwXMLout);
以上代码,建立一个中国移动的cmnet连接点。关于DMProcessConfigXML我知道得也就是这么多。更多的内容大家只好google了。