Windows Mobile中GPRS连接网络

Windows Mobile程序中如果要使用http或socket连接服务器,需要先连接网络。可以使用ConnMgrEstablishConnectionSync函数来连接。

DWORD  dwStatus = 0;
HANDLE hConnection = NULL;

CONNMGR_CONNECTIONINFO sConInfo;
memset(&sConInfo, 0 ,sizeof(CONNMGR_CONNECTIONINFO));

sConInfo.cbSize = sizeof(CONNMGR_CONNECTIONINFO);
sConInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET;
sConInfo.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;

sConInfo.dwFlags = CONNMGR_FLAG_PROXY_HTTP
       |CONNMGR_FLAG_PROXY_WAP
       |CONNMGR_FLAG_PROXY_SOCKS4
       |CONNMGR_FLAG_PROXY_SOCKS5;

sConInfo.bExclusive  = FALSE;
sConInfo.bDisabled   = FALSE;
sConInfo.guidDestNet = IID_DestNetWAP;

ConnMgrEstablishConnectionSync(&sConInfo, &hConnection, 15000, &dwStatus);


如果知道一个接入点的名称,则可以通过ConnMgrEnumDestinations得到相应接入点的guidDestNet。然后可以使用底层的INET接口连接HTTP了。完了吗?没有。还有个问题:代理服务器。我们都知道,移动的CMNET不需要代理,CMWAP则需要。接入点中可能含有代理服务器信息,而且接入类型包括HTTP、WAP、安全WAP、Socks等等,每一种都可能需要不同的代理。不要奢望ConnMgrEnumDestinations函数可以得到这么多的东东。

事实上,微软是提供了一个函数的,这就是传说中的ConnMgrProviderMessage。怎么样,这下总该圆满了吧?...还没完,接着往下走。

我测的结果,在真机上,这个函数从来没有成功过,Never。郁闷之极。与签名有关吗?未可知。

正面强攻不行。打枪的不要,悄悄的进村。我们来看看手机的注册表。在HKEY_LOCAL_MACHINE/Comm/ConnMgr项下,有详细的接入点的信息。Destinations子项下列出了手机所有的接入点,相应的键值有DestId这一项。我们的目光再跳到与ConnMgr平级的Providers项,也有很多信息,其中一子项{EF097F4C-DC4B-4c98-8FF6-AEF805DC0E8E},快接近我们要的宝贝了。该项有很多子项,我们遍历每一项,直到找到一个键值SrcId与我们上面说的DestId相等。看到了吧,与SrcId平级的键值有很多,不过我们目前需要的就那么两项,Type和Proxy。Type就是上面说的接入类型(HTTP、WAP、安全WAP、Socks等),而Proxy正是我们凄凄惨惨戚戚寻寻觅觅的一串字符

以上是Windows Mobile5.0的结果。在Pocket PC2003和Smartphone2003中,HKEY_LOCAL_MACHINE/Comm/ConnMgr对应为HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/ConnMgr。

至此,寻宝经历告一段落。

看一下微软提供的一个Demo:

#include<windows.h>
#include<wininet.h>
#include<iostream.h>

DWORD dwNumKSent;
DWORD dwNumKToSend;
DWORD dwNumBytesComplete = 0;

char lpOutBuf[1024];

HANDLE hConnectedEvent, hRequestCompleteEvent;

HINTERNET hInstance, hConnect, hRequest;

char *lpszUrl, *lpszServer;

BOOL bAllDone = FALSE;

void __stdcall Callback(HINTERNET hInternet,
              DWORD dwContext,
              DWORD dwInternetStatus,
              LPVOID lpStatusInfo,
              DWORD dwStatusInfoLen);

void main(int argc, char *argv[])
{
    if (argc != 4)
    {
        cout << "Usage: sendreqexasync <server> <url> <size in kilobytes>" << endl;
        cout << "   Example: sendreqexasync www.foo.com /postfolder/upload.exe 256" << endl;
        return;
    }

    lpszServer = argv[1];
    lpszUrl = argv[2];
    dwNumKToSend = atoi(argv[3]);

    FillMemory(lpOutBuf, 1024, 'A');

    hConnectedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    hRequestCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    hInstance = InternetOpen("sendreqexasync",
                               INTERNET_OPEN_TYPE_PRECONFIG,
                               NULL,
                               NULL,
                               INTERNET_FLAG_ASYNC);//异步

    if (hInstance == NULL)
    {
        cout << "InternetOpen failed, error " << GetLastError();
        return;
    }

    if (InternetSetStatusCallback(hInstance,
                                  (INTERNET_STATUS_CALLBACK)&Callback) == INTERNET_INVALID_STATUS_CALLBACK)
    {
        cout << "InternetSetStatusCallback failed, error " << GetLastError();
        return;
    }

    hConnect = InternetConnect(hInstance,
                               lpszServer, //服务器
                               INTERNET_DEFAULT_HTTP_PORT,
                               NULL,
                               NULL,
                               INTERNET_SERVICE_HTTP,
                               0,
                               1);
    if (hConnect == NULL)
    {
        if (GetLastError() != ERROR_IO_PENDING)
        {
            cout << "InternetConnect failed, error " << GetLastError();
            return;
        }
        WaitForSingleObject(hConnectedEvent, INFINITE);
    }

    hRequest = HttpOpenRequest(hConnect,
                               "POST",
                               lpszUrl,//页面
                               NULL,
                               NULL,
                               NULL,
                               INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE,
                               2);
    if (hRequest == NULL)
    {
        if (GetLastError() != ERROR_IO_PENDING)
        {
            cout << "HttpOpenRequest failed, error " << GetLastError();
            return;
        }
        WaitForSingleObject(hRequestCompleteEvent, INFINITE);
    }

    INTERNET_BUFFERS IntBuff;

    FillMemory(&IntBuff, sizeof(IntBuff), 0);
    IntBuff.dwStructSize= sizeof(IntBuff);
    IntBuff.dwBufferTotal = 1024*dwNumKToSend;
    IntBuff.lpcszHeader = "Content-Type: text/text/r/n";
    IntBuff.dwHeadersLength = lstrlen(IntBuff.lpcszHeader);

    if (!HttpSendRequestEx(hRequest,
                           &IntBuff,
                           NULL,
                           0,
                           2))
    {
        if (GetLastError() != ERROR_IO_PENDING)
        {
            cout << "HttpSendRequestEx failed, error " << GetLastError();
            return;
        }
        cout << "HttpSendRequestEx called successfully" << endl;
        cout.flush();

        WaitForSingleObject(hRequestCompleteEvent, INFINITE);//等待信号
    }

        //此处
    for(dwNumKSent = 0; dwNumKSent < dwNumKToSend; dwNumKSent++)
    {
        DWORD dwBytesWritten;

        if(!InternetWriteFile(hRequest,
                               lpOutBuf,
                               1024,
                               &dwBytesWritten))
        {
            if (GetLastError() != ERROR_IO_PENDING)
            {
                cout << "InternetWriteFile failed, error " << GetLastError();
                return;
            }
            else
            {
                cout << "InternetWriteFile completing asynchronously" << endl;
                cout.flush();
                WaitForSingleObject(hRequestCompleteEvent, INFINITE);//
            }
        }
    }

    cout << "Calling HttpEndRequest" << endl;
    cout.flush();
    if (!HttpEndRequest(hRequest, NULL, HSR_INITIATE, 2))
    {
        if (GetLastError() == ERROR_IO_PENDING)
        {
            cout << "HttpEndRequest called" << endl;
            cout.flush();
            WaitForSingleObject(hRequestCompleteEvent, INFINITE);
        }
        else
        {
            cout << "HttpEndRequest failed, error " << GetLastError() << endl;
            return;
        }
    }


    cout << "------------------- Read the response -------------------" << endl;
    char lpReadBuff[256];

    do
    {
        INTERNET_BUFFERS InetBuff;
        FillMemory(&InetBuff, sizeof(InetBuff), 0);
        InetBuff.dwStructSize = sizeof(InetBuff);
        InetBuff.lpvBuffer = lpReadBuff;
        InetBuff.dwBufferLength = sizeof(lpReadBuff) - 1;
        
        cout << "Calling InternetReadFileEx" << endl;
        cout.flush();

        if (!InternetReadFileEx(hRequest,
                              &InetBuff,
                              0, 2))
        {
            if (GetLastError() == ERROR_IO_PENDING)
            {
                cout << "Waiting for InternetReadFile to complete" << endl;
                cout.flush();
                WaitForSingleObject(hRequestCompleteEvent, INFINITE);
            }
            else
            {
                cout << "InternetReadFileEx failed, error " << GetLastError();
                cout.flush();
                return;
            }
        }

        lpReadBuff[InetBuff.dwBufferLength] = 0;
        cout << lpReadBuff;
        cout.flush();

        if (InetBuff.dwBufferLength == 0)
            bAllDone = TRUE;

    } while (bAllDone == FALSE);

    cout << endl << endl << "------------------- Request Complete ----------------" << endl;

}

void __stdcall Callback(HINTERNET hInternet,
              DWORD dwContext,
              DWORD dwInternetStatus,
              LPVOID lpStatusInfo,
              DWORD dwStatusInfoLen)
{
    cout << "Callback dwInternetStatus: " << dwInternetStatus << " Context: " << dwContext << endl;
    cout.flush();

    switch(dwContext)
    {
    case 1: // Connection handle
        if (dwInternetStatus == INTERNET_STATUS_HANDLE_CREATED)
        {
            INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
            hConnect = (HINTERNET)pRes->dwResult;
            cout << "Connect handle created" << endl;
            cout.flush();
            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;
                cout << "Request handle created" << endl;
                cout.flush();
            }
            break;

        case INTERNET_STATUS_REQUEST_SENT:
            {
                DWORD *lpBytesSent = (DWORD*)lpStatusInfo;
                cout << "Bytes Sent: " << *lpBytesSent << endl;
                dwNumBytesComplete += *lpBytesSent;
            }
            break;

        case INTERNET_STATUS_REQUEST_COMPLETE:
            {
                INTERNET_ASYNC_RESULT *pAsyncRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
                cout << "Function call finished" << endl;
                cout << "dwResult: " << pAsyncRes->dwResult << endl;
                cout << "dwError:  " << pAsyncRes->dwError << endl;
                cout.flush();
                SetEvent(hRequestCompleteEvent);
            }
            break;

        case INTERNET_STATUS_RECEIVING_RESPONSE:
            cout << "Receiving Response" << endl;
            cout.flush();
            break;

        case INTERNET_STATUS_RESPONSE_RECEIVED:
            {
                DWORD *dwBytesReceived = (DWORD*)lpStatusInfo;
                cout << "Received " << *dwBytesReceived << endl;
                cout.flush();
            }
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值