您的位置:首页 > 理论基础 > 计算机网络

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

原帖由 zhaxg 于 2009-10-13 10:57 发表


C大,我很崇拜你哦~


呵呵,其实在网络编程这块,我也处于摸索阶段~

这里给出我的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 ...


我也是。。。

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

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

[color=gray][/color]

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

好贴要顶

好贴要顶 留名

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

原帖由 snox 于 2009-11-29 20:44 发表


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


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

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 发表


你这样做就无法设置超时了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: