wininet异步代理的编程
来源:互联网 发布:智库研究员 知乎 编辑:程序博客网 时间:2024/04/28 05:29
// testwinInet.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <WINDOWS.H>#include <WININET.H>#include <STDLIB.H>#include <string>#include <IOSTREAM.H>#pragma comment(lib,"wininet.lib")using namespace std;void CALLBACK InternetStatusCallback( HINTERNET hInternet, DWORD dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength);HANDLE hEvent[3];HINTERNET hFile;HINTERNET hNet;HINTERNET hSession,hConnect,hRequest;int WaitExitEvent(){ //return 1; DWORD dwRet = ::WaitForMultipleObjects(3, hEvent, FALSE, 30000);//INFINITE); int x=-1; switch (dwRet) { //句柄被创建事件或者读数据请求成功完成事件 case WAIT_OBJECT_0: x=0; cout<<"WAIT_OBJECT_0"<<endl; //句柄被关闭事件 break; case WAIT_OBJECT_0+1: x=1; cout<<"WAIT_OBJECT_1"<<endl; //用户要求终止子线程事件或者发生错误事件 break; case WAIT_OBJECT_0+2: x=2; cout<<"WAIT_OBJECT_2"<<endl; break; default: cout<<"WaitForMultipleObjects time out"<<endl; return -1; } return x;}// 支持代理设置, 是否异步设置; 采用事件驱动void WinINet3(bool setProxy, bool ASYNC){ hSession=NULL; hConnect=NULL; hRequest=NULL;int i; for (i = 0; i < 3; i++) { hEvent[i] = CreateEvent( NULL, // default security attributes FALSE, // auto-reset event object FALSE, // initial state is nonsignaled NULL); // unnamed object if (hEvent[i] == NULL) { printf("CreateEvent error: %d\n", GetLastError() ); ExitProcess(0); } } char *url = "http://down.360safe.com/setup.exe"; char *pip = "down.360safe.com"; char *paim = "/setup.exe"; // step 1 if(ASYNC) cout<<"异步模式"<<endl; // setProxy =false; if(setProxy) { cout<<"代理模式"<<endl; if(ASYNC) hSession = InternetOpen("name",INTERNET_OPEN_TYPE_DIRECT,//|INTERNET_OPEN_TYPE_PROXY,// INTERNET_OPEN_TYPE_PROXY,NULL,NULL,INTERNET_FLAG_ASYNC); // 异步 else hSession = InternetOpen("name",INTERNET_OPEN_TYPE_PROXY,NULL,NULL,0); // 同步 } else { if(ASYNC) hSession = InternetOpen("name",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,INTERNET_FLAG_ASYNC); // 异步 else hSession = InternetOpen("name",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); // 同步 } if(!hSession){ DWORD er = ::GetLastError(); cout<<"InternetOpen error"<<endl;//, "Err", MB_OK); return; } if(ASYNC) { //Sleep(500); INTERNET_STATUS_CALLBACK res = ::InternetSetStatusCallback(hSession,InternetStatusCallback); if(res == INTERNET_INVALID_STATUS_CALLBACK) { cout<<"InternetSetStatusCallback failed, so return "<<endl; return ; } else { cout<<"InternetSetStatusCallback succeed, so go on "<<endl; } //Sleep(500); } char strProxyList[MAX_PATH], strUsername[64], strPassword[64]; strcpy(strProxyList, "SOCKS=58.56.87.2:1080"); // 写上socks怎么就无效了呢???SOCKS5=172.18.132.27:1080 strcpy(strUsername, "user01"); strcpy(strPassword, "baidu"); INTERNET_PROXY_INFO proxy; proxy.dwAccessType = INTERNET_OPEN_TYPE_PROXY; proxy.lpszProxy = strProxyList; proxy.lpszProxyBypass = NULL; if( setProxy &&!InternetSetOption(hSession,INTERNET_OPTION_PROXY ,&proxy,sizeof(INTERNET_PROXY_INFO))) { cout<<"InternetSetOption failed"<<endl; return ; } // step 2 //如果明确知道需要认证,第4,5个参数可以输入用户名,密码"administrator","password" //第2,3个参数为目标主机IP、端口号(不是代理服务器的参数) hConnect = InternetConnect(hSession,pip,INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,INTERNET_FLAG_RELOAD,0); if(!ASYNC &&!hConnect){ cout<<"同步,InternetConnect error"<<endl;//, "Err", MB_OK); return; } if( ASYNC&& hConnect== NULL)// 异步需要等待 竟然直接创建好了 { DWORD dwError = ::GetLastError(); if (dwError != ERROR_IO_PENDING) { cout<<"CHttpDownload::OpenInternetConnection| 连接失败" <<endl; return ; } else // { cout<<"hConnect == NULL, so run WaitExitEvent"<<endl; WaitExitEvent(); // 等待成功创建 // 这里应该等待 这里应该显示一次呀 ::ResetEvent(hEvent[0]); ::ResetEvent(hEvent[1]); ::ResetEvent(hEvent[2]); } } cout<<"step 2 :InternetConnect succeed"<<endl; // ::InternetSetStatusCallback(hConnect,InternetStatusCallback); // step 3!!! char szHead[] = "Accept: *NULL,0,0"; // no request; CONST TCHAR *szAcceptType="__HTTP_ACCEPT_TYPE"; hRequest = ::HttpOpenRequest(hConnect, "GET", paim, HTTP_VERSION, "", &szAcceptType, INTERNET_FLAG_RELOAD|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_NO_CACHE_WRITE, 0); //::HttpAddRequestHeaders( hRequest, __HTTP_ACCEPT, strlen(__HTTP_ACCEPT), HTTP_ADDREQ_FLAG_REPLACE); if (!ASYNC&& !hRequest){ cout<<"同步,HttpOpenRequest error"<<endl;//, "Err", MB_OK); return; } if( ASYNC&& hRequest== NULL)// 异步需要等待 { int er = GetLastError(); DWORD dwError = ::GetLastError(); if (dwError != ERROR_IO_PENDING) { cout<<"CHttpDownload::OpenInternetConnection | 连接失败" <<endl; return ; } else // { cout<<"hRequest == NULL, so run WaitExitEvent"<<endl; WaitExitEvent(); // 等待成功创建 ::ResetEvent(hEvent[0]); ::ResetEvent(hEvent[1]); ::ResetEvent(hEvent[2]); } } //Sleep(10000); cout << "step 3 : HttpOpenRequest success"<<endl; //::InternetSetStatusCallback(hRequest,InternetStatusCallback); ////////////////////////////////////////////// if (setProxy ) { // InternetSetOption 不要异步等待 if( !InternetSetOption(hRequest,INTERNET_OPTION_PROXY_USERNAME ,strUsername,strlen(strUsername)+1)) { cout<<"InternetSetOption Username failed"<<endl; return ; } if( !InternetSetOption(hRequest,INTERNET_OPTION_PROXY_PASSWORD ,strPassword,strlen(strPassword)+1)) { cout<<"InternetSetOption Password failed"<<endl; return ; } } // step 4 //HttpSendRequest(hRequest,NULL,0,NULL,0); //Sleep(3000); ::ResetEvent(hEvent[0]); ::ResetEvent(hEvent[1]); ::ResetEvent(hEvent[2]); if(!::HttpSendRequest(hRequest,NULL,0,NULL,0)) // 为什么失败??? { //Sleep(3000); if(!ASYNC)// 同步 { DWORD dwError = ::GetLastError(); cout<<"同步,HttpSendRequest failed, GetLastError=="<<dwError<<endl; return ; } else { Sleep(3000); DWORD dwError = ::GetLastError(); cout<<"dwError =="<<dwError<<endl; if (dwError != ERROR_IO_PENDING) { cout<<"dwError != ERROR_IO_PENDING, so quit,dwError =="<<dwError<<endl; return ; } else // { cout<<"HttpSendRequest, so run WaitExitEvent"<<endl; Sleep(3000); //if(WaitExitEvent()!=2)//; // 等待成功创建 等待是否不对??? { cout<<"had not recv complete event, so quit"<<endl; // return ; } } } } Sleep(3000); cout << "step 4: HttpSendRequest success!"<<endl; int bufh[1000]; DWORD dwLen,dwIndex; // 判断状态码; char m_dwStatusCode[90]; DWORD dwStatusSize = sizeof(m_dwStatusCode); DWORD dwByteToRead = 0; DWORD dwSizeOfRq = 4; DWORD dwBytes = 0; //这三个值分别存储文件的大小,HttpQueryInfo内容的大小和总共读取的字节数。 //HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwByteToRead, &dwSizeOfRq, NULL); //需要说明的是 HttpQueryInfo 并不进行网络操作,因此它不需要进行异步操作的处理。 if (!HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwByteToRead, &dwSizeOfRq, NULL)) { // 这里失败了??? DWORD dwError = ::GetLastError(); cout<<"HttpQueryInfo failed, so return, GetLastError() =="<<dwError<<endl; return ; } FILE * pFile = fopen("d://baidu01.exe", "wb" ); //ofstream mfile("out.txt");//定义文件输出流ouf,并关联到out.txt i=0; DWORD leftB = dwByteToRead; cout<<"开始下载"<<endl; if( !ASYNC) // 同步下载 { while(true) { const int MAX_BUFFER_SIZE = 65536; unsigned long nSize = 0; char szBuffer[MAX_BUFFER_SIZE+2]; int num = MAX_BUFFER_SIZE; if( leftB < num)num = leftB; BOOL bRet = ::InternetReadFile(hRequest, szBuffer, num, &nSize); // 异步 需要等待 leftB -= nSize; cout<<i++<<" size: "<<nSize<<endl; if(!bRet || nSize <= 0) break; fwrite(szBuffer, sizeof(char), nSize, pFile); } } else // 异步下载 { INTERNET_BUFFERS i_buf = {0}; i_buf.dwStructSize = sizeof(INTERNET_BUFFERS); i_buf.lpvBuffer = new TCHAR[10242]; i_buf.dwBufferLength = 10240; for( DWORD i=0;i<dwByteToRead;) { //重置读数据事件 ::ResetEvent( hEvent[0]); int num = 10240; if(dwByteToRead-i<10240) { num = dwByteToRead-i; i_buf.dwBufferLength = dwByteToRead-i; } if (FALSE == ::InternetReadFileEx(hRequest, &i_buf, IRF_ASYNC, NULL)) { if (ERROR_IO_PENDING == ::GetLastError()) { if ( NULL)//WaitExitEvent()!=2) { delete[] i_buf.lpvBuffer; return ; } } else { cout<<"down failed,so return"<<endl; delete[] i_buf.lpvBuffer; return ; } } else { //在网络传输速度快,步长较小的情况下, //InternetReadFileEx 经常会直接返回成功, //因此要判断是否发生了用户要求终止子线程事件。 cout<<"网络很好,InternetReadFileEx返回true"<<endl; // 暂不考虑用户退出 } i += i_buf.dwBufferLength; // 最后一次写多了!!! fwrite(i_buf.lpvBuffer, sizeof(char), i_buf.dwBufferLength, pFile); cout<<"i== "<<i<<endl; //保存数据 //通知主线程下载进度 } } InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hSession); cout<<"success download file"<<endl; return;}int main(int argc, char* argv[]){printf("Starting .......!\n");WinINet3(true,true); return 1;}void OnInternetHandleCreated(HINTERNET hInternet, LPINTERNET_ASYNC_RESULT lpInetStatusResult){ if(NULL == lpInetStatusResult) { //ATLASSERT( 0 ); return; } hFile = HINTERNET(lpInetStatusResult->dwResult); HINTERNET hInet = HINTERNET(lpInetStatusResult->dwResult); DWORD dwInetHandleType; DWORD dwTypeLen = sizeof(dwInetHandleType); InternetQueryOption( hInet, INTERNET_OPTION_HANDLE_TYPE, &dwInetHandleType, &dwTypeLen); switch(dwInetHandleType) { case INTERNET_HANDLE_TYPE_CONNECT_HTTP: //CloseInternetConnection(); // 这里是何意???? 通过回调 设置httpConnect hConnect = hInet; // break; case INTERNET_HANDLE_TYPE_HTTP_REQUEST: //CloseInternetFile(); // 这里是何意?? 通过回调设置httpFile hRequest = hInet; // break; default: break; } cout<<"OnInternetHandleCreated, so ::SetEvent(hEvent[0])"<<endl; // HANDLE已创建事件(异步控制) ::SetEvent(hEvent[0]);}void OnInternetRequestComplete(HINTERNET hInternet, LPINTERNET_ASYNC_RESULT lpInetStatusResult){ if( lpInetStatusResult == NULL ) { //ATLASSERT( 0 ); return; } cout<<"OnInternetRequestComplete, so ::SetEvent(hEvent[2])"<<endl; // 激发请求完成事件(异步控制) ::SetEvent(hEvent[0]);}void CALLBACK InternetStatusCallback( HINTERNET hInternet, DWORD dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength ){ cout<<"进入回调"<<endl; switch (dwInternetStatus) { case INTERNET_STATUS_RESOLVING_NAME: break; case INTERNET_STATUS_NAME_RESOLVED: break; case INTERNET_STATUS_CONNECTING_TO_SERVER: break; case INTERNET_STATUS_CONNECTED_TO_SERVER: break; case INTERNET_STATUS_SENDING_REQUEST: break; case INTERNET_STATUS_REQUEST_SENT: break; case INTERNET_STATUS_RECEIVING_RESPONSE: break; case INTERNET_STATUS_RESPONSE_RECEIVED: break; case INTERNET_STATUS_CLOSING_CONNECTION: break; case INTERNET_STATUS_CONNECTION_CLOSED: break; case INTERNET_STATUS_HANDLE_CREATED: cout<<"回调是INTERNET_STATUS_HANDLE_CREATED"<<endl; OnInternetHandleCreated(hInternet, LPINTERNET_ASYNC_RESULT(lpvStatusInformation)); break; case INTERNET_STATUS_HANDLE_CLOSING: break; case INTERNET_STATUS_REQUEST_COMPLETE: cout<<"回调是INTERNET_STATUS_REQUEST_COMPLETE"<<endl; OnInternetRequestComplete(hInternet, LPINTERNET_ASYNC_RESULT(lpvStatusInformation)); break; case INTERNET_STATUS_REDIRECT: case INTERNET_STATUS_INTERMEDIATE_RESPONSE: case INTERNET_STATUS_STATE_CHANGE: default: break; }}
- wininet异步代理的编程
- WinINet的异步调用方式
- 简单的WinInet编程
- 使用WinInet API 进行异步编程
- WinInet编程中如何使用异步
- WinInet 编程中如何使用异步
- WinInet编程中如何使用异步
- WInINet编程中如何使用异步
- 异步WinInet
- wininet异步
- WinInet API 的异步方式使用
- WinInet API 的异步方式使用
- WinInet API 的异步方式使用
- Windows Mobile下WinInet的异步使用方法
- Windows Mobile下WinInet的异步使用方法
- WinInet API 的异步方法使用
- WinInet API 的异步方式使用
- Windows Mobile下WinInet的异步使用方法
- Hadoop是什么?
- CppUnit类结构UML图
- javascript 实现sleep效果
- Flex ExternalInterface调用javascript
- vim几个实用命令
- wininet异步代理的编程
- 禁止eclipse对压缩过的JS提示报错
- poj1201
- UVa 10706 - Number Sequence(POJ 1019)
- 数据库三范式(下)
- 理解Qt多线程类
- MSVC2008 MFC, 无法打开.rc文件, rc:opened in another editor
- C++的继承
- 事件营销让面包圈有关注 但产品好才是真的好