SDK网络连接/多线程示例代码

来源:互联网 发布:网络安全产品对比 编辑:程序博客网 时间:2024/05/21 10:59

[code]        static BOOL SendMsg(wstring url)
        {
                DWORD dwNetWorkStatus = QueryNetWorkStatus();
                HINTERNET hSession = NULL,hConnection = NULL,hOpenRequest = NULL;

                //如果没有网络则连接网络
                if (dwNetWorkStatus == NETWORK_NONE)
                {
                        Dial_StartGprsConnect2(0,GPRS_FORCE_APP_TYPE);
                        //联网后重新查询网络类型
                        dwNetWorkStatus = QueryNetWorkStatus();
                }

                //判定是否为cmwap,使用代理
                if (dwNetWorkStatus == NETWORK_EDGE_PROXY)
                        hSession = InternetOpen(L"Meizu", INTERNET_OPEN_TYPE_PROXY, L"10.0.0.172:80", NULL, 0);
                else
                        hSession = InternetOpen(L"Meizu", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);

                string url_utf8 = MzConvert::UnicodeToUTF8(url);//编码
                url = ::MzConvert::string2wstring(url_utf8);

                //打开链接,获取文件
                HINTERNET hHttpFile = InternetOpenUrlW(hSession, url.c_str(), NULL, 0,INTERNET_FLAG_RELOAD, 0);

                //读取文件内容
                char buf[1024]={0};
                DWORD dwRead=0;
                BOOL  ReadReturn=InternetReadFile(hHttpFile,(LPVOID)buf,1024+1,&dwRead);

                wstring str = MzConvert::UTF8ToUnicode(string(buf));//解码

                //关闭连接
                InternetCloseHandle(hSession);

                return true;
        }[/code]这里面编码解码很重要的,不然中文乱码问题很头疼!

多线程:
声明:static DWORD WINAPI ThreadProc (LPVOID pArg);
          static wstring SEND = L"http://quickfetion.appspot.com/sendmsg?username=?;password=?;sendto=?;message=?";

定义:static DWORD WINAPI ThreadProc (LPVOID pArg)
{
        wstring *c = (wstring*)pArg;
        wstring url = wstring(*c);

        CQuickFxMainWnd::SendMsg(url);

        return 1;
}
调用:HANDLE hThread = CreateThread(NULL, 0, ::ThreadProc,&SEND, 0, 0);

这里注意函数定义形式,static关键字,还有全局概念,否则出现线程阻塞,不可访问资源的错误!

个人理解,各位高手莫要见笑!!!

附上编码解码的头文件:[code]
using namespace std;

class MzConvert
{
public:

    static wstring string2wstring(const string& s)
    {
        int len;
        int slength = (int)s.length() + 1;
        len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
        wchar_t* buf = new wchar_t[len];
        MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
        std::wstring r(buf);
        delete[] buf;
               
        return r;
    }
   

    static wstring ANSIToUnicode( const string& str )
    {
        int len = str.length();

        int unicodeLen = ::MultiByteToWideChar( CP_ACP, 0, str.c_str(), -1, NULL, 0 );

        wchar_t * pUnicode;
        pUnicode = new wchar_t[unicodeLen+1];

        memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));

        MultiByteToWideChar( CP_ACP, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen );


        wstring rt = ( wchar_t* )pUnicode;
        delete pUnicode;

        return rt;
    }


    static string UnicodeToANSI( const wstring& str )
    {
        char* pElementText;
        int iTextLen;

        // wide char to multi char
        iTextLen = WideCharToMultiByte( CP_ACP, 0, str.c_str(), -1, NULL, 0, NULL, NULL );

        pElementText = new char[iTextLen + 1];
        memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );

        WideCharToMultiByte( CP_ACP, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL );

        string strText = pElementText;
        delete[] pElementText;

        return strText;
    }


    static wstring UTF8ToUnicode( const string& str )
    {
        int len = str.length();
        int unicodeLen = ::MultiByteToWideChar( CP_UTF8, 0, str.c_str(), -1, NULL, 0 );

        wchar_t * pUnicode;
        pUnicode = new wchar_t[unicodeLen+1];
        memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));

        MultiByteToWideChar( CP_UTF8, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen );


        wstring rt = ( wchar_t* )pUnicode;
        delete pUnicode;

        return rt;
    }


    static string UnicodeToUTF8( const wstring& str )
    {
        char* pElementText;
        int iTextLen;

        // wide char to multi char
        iTextLen = WideCharToMultiByte( CP_UTF8, 0, str.c_str(), -1, NULL, 0, NULL, NULL );
        pElementText = new char[iTextLen + 1];

        memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );

        WideCharToMultiByte( CP_UTF8, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL );

        string strText = pElementText;
        delete[] pElementText;

        return strText;
    }

};[/code]

[[i] 本帖最后由 zhaxg 于 2009-10-13 08:59 编辑 [/i]]

zhaxg 发表于 2009-10-10 08:39

自己顶一个!!!!!!!

zhaxg 发表于 2009-10-10 12:37

高手呢,在线等啊

zhaxg 发表于 2009-10-10 12:49

高手呢,在线等啊

tanzhen21 发表于 2009-10-12 11:22

回复 1楼 zhaxg 的帖子

如果是有中文字符,提交的时候必需要编码成URL编码(CUrlEncodeUnicode)提交!
如果需要URL编码解码的类,请联系我!

[[i] 本帖最后由 tanzhen21 于 2009-10-12 11:23 编辑 [/i]]

zhaxg 发表于 2009-10-13 09:04

谢谢各位支持,问题基本解决了,现在把我的成果和大家分享出来,希望对刚入门C++的MY有一些帮助,高手就飘过了,也希望高手们多多分享自己的经验!

szlbz 发表于 2009-10-13 09:14

很好,又学到东西啦,谢谢!

cddjr 发表于 2009-10-13 09:34

我是用HttpOpen/SendRequest,
用三条线程[code]
protected:
    // AsyncThread负责HttpOpenRequest, 并创建Send与Read线程
    static DWORD AsyncThread(LPVOID lpParams);
    static DWORD SendThreadProc(LPVOID lpParams);
    static DWORD ReadThreadProc(LPVOID lpParams);
[/code]

[[i] 本帖最后由 cddjr 于 2009-10-13 20:38 编辑 [/i]]

winself 发表于 2009-10-13 10:02

不错不错,学习学习[m8em005]

zhaxg 发表于 2009-10-13 10:57

C大,我很崇拜你哦~

cddjr 发表于 2009-10-13 20:51

[quote]原帖由 [i]zhaxg[/i] 于 2009-10-13 10:57 发表[url=http://bbs.meizu.com/redirect.php?goto=findpost&pid=17863460&ptid=1229345][img]http://bbs.meizu.com/images/common/back.gif[/img][/url]
C大,我很崇拜你哦~ [/quote]

呵呵,其实在网络编程这块,我也处于摸索阶段~
这里给出我的myQQ的HTTP通信模块的部分主要代码
一起找找BUG吧

[code]
// DoPost:提交数据
// 创建日期: 2009-10-09
// 最后修订: 2009-10-11
LPVOID CMyHTTP::DoPost(PTCHAR page,PCHAR data,PTCHAR cookies, LPTHREAD_START_ROUTINE lpOnRecvCompleted)
{
thread_info *pTI = new thread_info(page,true,data,cookies,lpOnRecvCompleted);//不要忘记释放
pTI->m_obj01 = this;//CMyHTTP;
HANDLE hThread = CreateThread(NULL,0,CMyHTTP::AsyncThread,pTI,0,NULL);
return pTI;
}
[/code]

[b]AsyncThread[/b]
[code]
// AsyncThread负责HttpOpenRequest, 并创建Send与Read线程
// 创建日期: 2009-10-09
// 最后修订: 2009-10-11
DWORD CMyHTTP::AsyncThread(LPVOID lpParams)
{
thread_info *pTI =(thread_info *)lpParams;
CMyHTTP *http=(CMyHTTP *)pTI->m_obj01;
if (http->initinet()==false)
{
  pTI->lastERRcode = 0x800C0101;
  return pTI->lastERRcode;
}
if (pTI->m_hRequest == NULL)
{
  if (pTI->isPOST == true){                         // HTTP/1.1的协议,默认长连接
   pTI->m_hRequest =HttpOpenRequest(http->m_hConnect,_T("POST"),pTI->m_page,_T("HTTP/1.1"),NULL,NULL,INTERNET_FLAG_NO_COOKIES| INTERNET_FLAG_NO_CACHE_WRITE,NULL);
  }else{
   pTI->m_hRequest =HttpOpenRequest(http->m_hConnect,_T("GET"),pTI->m_page,_T("HTTP/1.1"),NULL,NULL,INTERNET_FLAG_NO_COOKIES| INTERNET_FLAG_NO_CACHE_WRITE,NULL);
  }
  if(pTI->m_hRequest == NULL)
  {
   pTI->lastERRcode = 0x800C0102;
   return pTI->lastERRcode;
  }
  if (pTI->isPOST == true)
  {
   HttpAddRequestHeaders(pTI->m_hRequest,_T("Content-Type:application/x-www-form-urlencoded/r/n"),-1,HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDREQ_FLAG_ADD);
  }
  if (pTI->m_cookie.IsEmpty()==false)
  {
  HttpAddRequestHeaders(pTI->m_hRequest,CMyString(CMyString(L"Cookie:")+pTI->m_cookie+ L"/r/n").C_Str(),-1,HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDREQ_FLAG_ADD);
   if ((http->isWAP==true))
   {
    HttpAddRequestHeaders(pTI->m_hRequest,_T("X-Wap-Proxy-Cookie:none/r/n"),-1,HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDREQ_FLAG_ADD);
   }
  }
  
}
pTI->lastERRcode = 0;
HANDLE hThread = CreateThread(NULL,0,CMyHTTP::SendThreadProc,pTI,0,NULL);
WaitForSingleObject(hThread,30000);//最多等30秒
CloseHandle(hThread); hThread = NULL;//关闭线程句柄
hThread = CreateThread(NULL,0,CMyHTTP::ReadThreadProc,pTI,0,NULL);
WaitForSingleObject(hThread,30000);//最多等30秒
CloseHandle(hThread); hThread = NULL;//关闭线程句柄
return 0;
}
[/code]

[b]在发送请求前调用:[/b]
[code]
//initinet():
//在HttpSendRequest前调用
//用于初始化Wininet,根据网络环境调节参数
//创建日期 2009-10-09
//最后修订 2009-10-13
//版本 v1.12
bool CMyHTTP::initinet(void)
{
SendMessageW(hwnd,HTTP_INIT,0,0);
DWORD dwNetWorkStatus = QueryNetWorkStatus();
switch(dwNetWorkStatus)
{
case NETWORK_NONE:
  {
   //
   if(NULL != m_hConnect)
    InternetCloseHandle(m_hConnect);
   if(NULL != m_hInternet)
    InternetCloseHandle(m_hInternet);
   m_hInternet = m_hConnect = NULL;
   //
   SendMessageW(hwnd,HTTP_GPRS_START,0,0);
   HRESULT ret = Dial_StartGprsConnect2(NULL,GPRS_FORCE_APP_TYPE);
   if(RESULT_OK == ret)
   {
    SendMessageW(hwnd,HTTP_GPRS_OK,0,0);
    if(NETWORK_EDGE_PROXY==QueryNetWorkStatus())
    {
     //CMWAP
     CMyHTTP::isWAP=true;
     CMyHTTP::isWLAN=false;
    }else {
     //CMNET
     CMyHTTP::isWAP=false;
     CMyHTTP::isWLAN=false;
    }
   }else {
    SendMessageW(hwnd,HTTP_GPRS_ERROR,0,0);
    return false;//拨号失败
   }
  }
  break;
case NETWORK_EDGE_PROXY:
  {
   CMyHTTP::isWAP=true;
   CMyHTTP::isWLAN=false;
  }
  break;
case NETWORK_wlan:
  {
   CMyHTTP::isWAP=false;
   CMyHTTP::isWLAN=true;
  }
  break;
default:
  {
   CMyHTTP::isWAP=false;
   CMyHTTP::isWLAN=false;
  }
  break;
}
if (NULL == m_hInternet)
{
  if(CMyHTTP::isWAP==true)
   m_hInternet = InternetOpen(L"MYQQ", INTERNET_OPEN_TYPE_PROXY, L"10.0.0.172:80", NULL, INTERNET_FLAG_DONT_CACHE);
  else////INTERNET_FLAG_DONT_CACHE 必须要有此标志,以确保下载的数据是最新的
   m_hInternet = InternetOpen(L"MYQQ", INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,INTERNET_FLAG_DONT_CACHE );
  if (NULL == m_hInternet)
  {
   SendMessageW(hwnd,HTTP_INIT_ERR,0,0);
   return false;
  }
}
if (NULL == m_hConnect)
{
  m_hConnect = InternetConnect(m_hInternet,Host,INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,0,0);
  if (NULL == m_hConnect)
  {
   /*
   是否应该打开,还有待研究..(10月13)
   InternetCloseHandle(m_hInternet);
   m_hInternet = NULL;
   */
   SendMessageW(hwnd,HTTP_INIT_ERR,0,0);
   return false;
  }
}
SendMessageW(hwnd,HTTP_INIT_OK,0,0);
return true;//OK!
}
[/code]

zhao214088 发表于 2009-10-17 13:03

[m8em005] [m8em005]

2005011lcj 发表于 2009-11-29 12:05

学习好贴!
[m8em009]

snox 发表于 2009-11-29 20:44

其实你没有必要开3个线程,开销太大了,完全就是一个线程可以做完的事情

afa311 发表于 2009-11-30 00:12

[quote]原帖由 [i]cddjr[/i] 于 2009-10-13 09:34 发表[url=http://bbs.meizu.com/redirect.php?goto=findpost&pid=17859938&ptid=1229345][img]http://bbs.meizu.com/images/common/back.gif[/img][/url]
我是用HttpOpen/SendRequest,
用三条线程
protected:
    // AsyncThread负责HttpOpenRequest, 并创建Send与Read线程
    static DWORD AsyncThread(LPVOID lpParams);
    static DWORD SendThreadProc(LPVOID ... [/quote]
我也是。。。

魅力逸族 发表于 2009-11-30 17:14

好东东一定要自己留一份,学习学习。:)

[color=gray][/color]

haizhi_w 发表于 2009-12-3 17:05

好贴要顶

好贴要顶 留名

cddjr 发表于 2009-12-3 22:12

[quote]原帖由 [i]snox[/i] 于 2009-11-29 20:44 发表[url=http://bbs.meizu.com/redirect.php?goto=findpost&pid=19791457&ptid=1229345][img]http://bbs.meizu.com/images/common/back.gif[/img][/url]
其实你没有必要开3个线程,开销太大了,完全就是一个线程可以做完的事情 [/quote]

你这样做就无法设置超时了。

C#做类似的网络功能是相当简单的,不过在C++上就复杂许多了。

[[i] 本帖最后由 cddjr 于 2009-12-3 22:15 编辑 [/i]]

jiemy_1987 发表于 2009-12-5 09:02

学习ing~!!

zzagly 发表于 2009-12-7 11:33

顶技术贴,正在研究中。。。

二进制的猫 发表于 2009-12-8 23:31

好东西,学习下。。。~
[m8em005]

vico22 发表于 2009-12-13 19:20

上面几个QQ、飞信的作者的软件都用过……路过崇拜中……

天犴传说 发表于 2009-12-21 16:40

留个记号

[color=gray][/color]

conearth 发表于 2009-12-27 20:48

new和delete不在相同代码段里使用,是不是有些危险?
返回值是栈地址,危险啊!

Jan_z 发表于 2009-12-28 01:32

我又看了一遍、还是没能看懂、还是回去看我的示例罢、

[color=gray][/color]

Jan_z 发表于 2009-12-28 01:37

有一天我会看懂的、我是魅族!

[color=gray][/color]

天犴传说 发表于 2009-12-28 15:44

留个记号啊

Fanshill 发表于 2009-12-29 00:43

呀研究,学习[m8em007]

MyLar 发表于 2010-1-7 11:02

我顶啊,正在找M8上面的拨号和GPRS方面的代码

luxi78 发表于 2010-1-7 11:38

[quote]原帖由 [i]cddjr[/i] 于 2009-12-3 22:12 发表[url=http://bbs.meizu.com/redirect.php?goto=findpost&pid=19969384&ptid=1229345][img]http://bbs.meizu.com/images/common/back.gif[/img][/url]


你这样做就无法设置超时了。

 

原创粉丝点击