[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]]
自己顶一个!!!!!!!
高手呢,在线等啊
高手呢,在线等啊
回复 1楼 zhaxg 的帖子
如果是有中文字符,提交的时候必需要编码成URL编码(CUrlEncodeUnicode)提交!
如果需要URL编码解码的类,请联系我!
[[i] 本帖最后由 tanzhen21 于 2009-10-12 11:23 编辑 [/i]]
谢谢各位支持,问题基本解决了,现在把我的成果和大家分享出来,希望对刚入门C++的MY有一些帮助,高手就飘过了,也希望高手们多多分享自己的经验!
很好,又学到东西啦,谢谢!
我是用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]]
不错不错,学习学习[m8em005]
C大,我很崇拜你哦~
[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);
elseINTERNET_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]
[m8em005] [m8em005]
学习好贴!
[m8em009]
其实你没有必要开3个线程,开销太大了,完全就是一个线程可以做完的事情
[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]
我也是。。。
好东东一定要自己留一份,学习学习。:)
[color=gray][/color]
好贴要顶
好贴要顶 留名
[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]]
学习ing~!!
顶技术贴,正在研究中。。。
好东西,学习下。。。~
[m8em005]
上面几个QQ、飞信的作者的软件都用过……路过崇拜中……
留个记号
[color=gray][/color]
new和delete不在相同代码段里使用,是不是有些危险?
返回值是栈地址,危险啊!
我又看了一遍、还是没能看懂、还是回去看我的示例罢、
[color=gray][/color]
有一天我会看懂的、我是魅族!
[color=gray][/color]
留个记号啊
呀研究,学习[m8em007]
我顶啊,正在找M8上面的拨号和GPRS方面的代码
[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]
你这样做就无法设置超时了。