SDK网络连接/多线程示例代码
2010-06-09 18:16
417 查看
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; }这里面编码解码很重要的,不然中文乱码问题很头疼!
多线程:
声明: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关键字,还有全局概念,否则出现线程阻塞,不可访问资源的错误!
个人理解,各位高手莫要见笑!!!
附上编码解码的头文件:
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; } };
[ 本帖最后由 zhaxg 于 2009-10-13 08:59 编辑 ]
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编码解码的类,请联系我!
[ 本帖最后由 tanzhen21 于 2009-10-12 11:23 编辑 ]
zhaxg
发表于 2009-10-13 09:04
谢谢各位支持,问题基本解决了,现在把我的成果和大家分享出来,希望对刚入门C++的MY有一些帮助,高手就飘过了,也希望高手们多多分享自己的经验!
szlbz
发表于 2009-10-13 09:14
很好,又学到东西啦,谢谢!
cddjr
发表于 2009-10-13 09:34
我是用HttpOpen/SendRequest,
用三条线程
protected: // AsyncThread负责HttpOpenRequest, 并创建Send与Read线程 static DWORD AsyncThread(LPVOID lpParams); static DWORD SendThreadProc(LPVOID lpParams); static DWORD ReadThreadProc(LPVOID lpParams);
[ 本帖最后由 cddjr 于 2009-10-13 20:38 编辑 ]
winself
发表于 2009-10-13 10:02
不错不错,学习学习[m8em005]
zhaxg
发表于 2009-10-13 10:57
C大,我很崇拜你哦~
cddjr
发表于 2009-10-13 20:51
呵呵,其实在网络编程这块,我也处于摸索阶段~
这里给出我的myQQ的HTTP通信模块的部分主要代码
一起找找BUG吧
// 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; }
AsyncThread
// 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; }
在发送请求前调用:
//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! }
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
原帖由 cddjr 于 2009-10-13 09:34 发表
我是用HttpOpen/SendRequest,
用三条线程
protected:
// AsyncThread负责HttpOpenRequest, 并创建Send与Read线程
static DWORD AsyncThread(LPVOID lpParams);
static DWORD SendThreadProc(LPVOID ...
我是用HttpOpen/SendRequest,
用三条线程
protected:
// AsyncThread负责HttpOpenRequest, 并创建Send与Read线程
static DWORD AsyncThread(LPVOID lpParams);
static DWORD SendThreadProc(LPVOID ...
我也是。。。
魅力逸族
发表于 2009-11-30 17:14
好东东一定要自己留一份,学习学习。:)
[color=gray][/color]
haizhi_w
发表于 2009-12-3 17:05
好贴要顶
好贴要顶 留名cddjr
发表于 2009-12-3 22:12
你这样做就无法设置超时了。
C#做类似的网络功能是相当简单的,不过在C++上就复杂许多了。
[ 本帖最后由 cddjr 于 2009-12-3 22:15 编辑 ]
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]原帖由 cddjr 于 2009-12-3 22:12 发表
你这样做就无法设置超时了。
相关文章推荐
- Windows Forms 实现安全的多线程详解(附带程序代码示例) (摘自网络)
- android网络编程之android连接网络的简单示例代码
- c#判断网络连接状态示例代码
- JDBC连接SQL Server2008基本格式及示例代码
- 一个非常标准的Java连接Oracle数据库的示例代码
- Android SDK示例代码学习(1)----BouncingBalls
- 简单网络爬虫代码示例
- Android网络通信的六种方式&示例代码
- Docker SSH连接docker容器的示例代码
- JAVA+ArcEngine开发(二):java arcengine连接sde示例代码
- win7局域网无法连接:错误代码0x80070035找不到网络路径
- 漫谈四种神经网络序列解码模型【附示例代码】 glimpse attention
- Android 实现无网络页面切换的示例代码
- win7系统 设置宽带连接网络共享 出现错误 无法启用共享访问 错误代码:0x80004005:未指定错误
- VBA连接mysql数据库 代码示例
- Java网络编程之(二): TCP的多线程连接
- 复习后台代码(与前面clentHttp连接网络结合)
- Java 多线程测试示例代码 (论坛回复摘要)
- J2ME中多线程网络连接编程的分析
- python的多线程、多进程代码示例