1、Winet API 支持使用IE代理、或者不使用代理、或者使用自定义代理三种方式。
2、使用自定义代理的话,支持HTTP代理,SOCKS代理,但是SOCKS代理不知支持用户名密码,HTTP代理支持
3、这里写了一个使用Winet API写的测试程序,测试Winet API对各种代理的支持,截图如下:
4、下面是程序源码:
void GetLastErrorMessage(DWORD dwError, LPTSTR lpBuffer, DWORD nSize)
{ if (lpBuffer == NULL || nSize == 0) return; HLOCAL hLocal = NULL; BOOL rlt = ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwError, LANG_NEUTRAL, (LPTSTR)&hLocal, 0, NULL); if (!rlt) { HMODULE hDll = ::LoadLibraryEx(_T("netmsg.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES); if (hDll != NULL) { ::FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM, hDll, dwError, LANG_NEUTRAL, (LPTSTR)&hLocal, 0, NULL); ::FreeLibrary(hDll); } } //FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_FROM_SYSTEM, //NULL, dwError, LANG_NEUTRAL, (PTSTR)&hLocal, 0, NULL); if (hLocal) { lpBuffer[nSize-1] = 0; _tcsncpy(lpBuffer, (LPTSTR)::LocalLock(hLocal), nSize - 1); ::LocalFree(hLocal); } else { _tcscpy(lpBuffer, _T("没找到对应的错误码信息")); } } BOOL ParseURL(const char* lpszURL, char* lpszServer, int& Port, char* lpszObject) { if (lpszURL == NULL || lpszServer == NULL || lpszObject == NULL) { return FALSE; } char szCanonicalizeUrl[INTERNET_MAX_URL_LENGTH] = {0}; DWORD dwCanonicalizeUrlLength = INTERNET_MAX_URL_LENGTH; BOOL bRet = ::InternetCanonicalizeUrlA(lpszURL, szCanonicalizeUrl, &dwCanonicalizeUrlLength, ICU_BROWSER_MODE); if (bRet) { URL_COMPONENTSA Components; ::memset(&Components, 0, sizeof(Components)); Components.dwStructSize = sizeof(Components); Components.lpszHostName = lpszServer ; Components.dwHostNameLength = INTERNET_MAX_URL_LENGTH; Components.lpszUrlPath = lpszObject; Components.dwUrlPathLength = INTERNET_MAX_URL_LENGTH; ::InternetCrackUrl(szCanonicalizeUrl, dwCanonicalizeUrlLength, 0, &Components); Port = Components.nPort; } return bRet; } DWORD DoInternetProxy(LPCTSTR lpszUrl, LPCTSTR lpszProxy) { /*The following example code shows how authentication could be handled using InternetSetOption. */ DWORDdwError = 0; HINTERNET hOpenHandle, hConnectHandle, hResourceHandle; hOpenHandle = InternetOpen("DoInternetProxy", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hOpenHandle) { if (lpszProxy && lpszProxy[0]) { printf("设置代理%s\n", lpszProxy); /*INTERNET_PER_CONN_OPTION_LIST List; INTERNET_PER_CONN_OPTION Option[1]; unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST); Option[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; Option[0].Value.pszValue = (char*)lpszProxy; List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST); List.pszConnection = NULL; List.dwOptionCount = 1; List.dwOptionError = 0; List.pOptions = Option; if(InternetSetOption(hOpenHandle, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, nSize))*/ INTERNET_PROXY_INFO ProxyInfo = {0}; ProxyInfo.dwAccessType = INTERNET_OPEN_TYPE_PROXY; ProxyInfo.lpszProxy = lpszProxy; ProxyInfo.lpszProxyBypass = NULL; if(InternetSetOption(hOpenHandle, INTERNET_OPTION_PROXY, &ProxyInfo, sizeof(ProxyInfo))) { /*char szYN[64]; printf("是否输入代理用户名/密码(输入Y/N)?"); scanf("%s", szYN); if (stricmp(szYN, "Y") == 0) { char szUsername[64] = {0}, szPassword[64] = {0}; printf("请输入代理用户名:"); scanf("%s", szUsername); printf("请输入代理用户密码:"); scanf("%s", szPassword); InternetSetOption(hOpenHandle, INTERNET_OPTION_PROXY_USERNAME, szUsername, strlen(szUsername)+1); InternetSetOption(hOpenHandle, INTERNET_OPTION_PROXY_PASSWORD, szPassword, strlen(szPassword)+1); }*/ } else { printf("设置代理失败!\n"); dwError = GetLastError(); } } char szServer[INTERNET_MAX_URL_LENGTH] = {0}; int nPort = 80; char szObject[INTERNET_MAX_URL_LENGTH] = {0}; if(ParseURL(lpszUrl, szServer, nPort, szObject)) { printf("测试URL:%s:%d %s\n", szServer, nPort, szObject); hConnectHandle = InternetConnect(hOpenHandle, szServer, nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0,0); if (hConnectHandle) { hResourceHandle = HttpOpenRequest(hConnectHandle, "GET", szObject, NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0); if (hResourceHandle) { do { if(HttpSendRequest(hResourceHandle, NULL, 0, NULL, 0)) { DWORDdwStatus = 0; DWORDdwStatusSize = sizeof(dwStatus); charszUsername[64] = {0}, szPassword[64] = {0}; HttpQueryInfo(hResourceHandle, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, &dwStatus, &dwStatusSize, NULL); if(dwStatus == HTTP_STATUS_PROXY_AUTH_REQ) {// Proxy Authentication Required // Insert code to set strUsername and strPassword. // cchUserLength is the length of strUsername and // cchPasswordLength is the length of strPassword. printf("请输入代理用户名:"); scanf("%s", szUsername); printf("请输入代理用户密码:"); scanf("%s", szPassword); // Insert code to safely determine cchUserLength and // cchPasswordLength. Insert appropriate error handling code. InternetSetOption(hResourceHandle, INTERNET_OPTION_PROXY_USERNAME, szUsername, strlen(szUsername)+1); InternetSetOption(hResourceHandle, INTERNET_OPTION_PROXY_PASSWORD, szPassword, strlen(szPassword)+1); continue; } if(dwStatus == HTTP_STATUS_DENIED) {// Server Authentication Required. // Insert code to set strUsername and strPassword. // cchUserLength is the length of strUsername and // cchPasswordLength is the length of strPassword. printf("请输入%s用户名:", szServer); scanf("%s", szUsername); printf("请输入%s用户密码:", szServer); scanf("%s", szPassword); // Insert code to safely determine cchUserLength and // cchPasswordLength. Insert error handling code as // appropriate. InternetSetOption(hResourceHandle, INTERNET_OPTION_USERNAME, szUsername, strlen(szUsername)+1); InternetSetOption(hResourceHandle, INTERNET_OPTION_PASSWORD, szPassword, strlen(szPassword)+1); continue; } } else { dwError = GetLastError(); } break; } while (1); // Insert code to read the data from the hResourceHandle // at this point. if (dwError == 0) { DWORD dwContentLength = 0; DWORD dwContentLengthSize = sizeof(dwContentLengthSize); if(!HttpQueryInfo( hResourceHandle, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwContentLength, &dwContentLengthSize, NULL)) { dwContentLength = 0; } printf("内容长度[%d]\n", dwContentLength); char szResource[256] = {0}; DWORD dwResourceLength = 255; if(!InternetReadFile( hResourceHandle, szResource, dwResourceLength, &dwResourceLength)) { printf("InternetReadFile失败!\n"); dwError = GetLastError(); } else { printf("%s%s\n", szResource, dwResourceLength<dwContentLength?"......":""); } } } else { printf("HttpOpenRequest失败!\n"); dwError = GetLastError(); } } else { printf("InternetConnect失败!\n"); dwError = GetLastError(); } } else { printf("解析%s地址失败!\n", lpszUrl); dwError = GetLastError(); } //重置代理 //INTERNET_PROXY_INFO ResetProxyInfo = {0}; //InternetSetOption(hOpenHandle, INTERNET_OPTION_PROXY, &ResetProxyInfo, sizeof(ResetProxyInfo)); } else { printf("InternetOpen失败!\n"); dwError = GetLastError(); } if(hResourceHandle) { InternetCloseHandle(hResourceHandle); hResourceHandle = NULL; } if(hConnectHandle) { InternetCloseHandle(hConnectHandle); hConnectHandle = NULL; } if (hOpenHandle) { InternetCloseHandle(hOpenHandle); hOpenHandle = NULL; } return dwError; } int main(int argc, char* argv[]) { //printf("Hello World!\n"); HANDLE hStdin = GetStdHandle( STD_OUTPUT_HANDLE ); SetStdHandle( STD_OUTPUT_HANDLE, (void *)0x7 ); char szBuffer[2048] = {0}; long flag = 1; //0 退出 do { SetConsoleTextAttribute( (void *)0x7, FOREGROUND_INTENSITY | FOREGROUND_INTENSITY ); /*if (argc < 2 || strcmp(argv[1],"help") == 0 || strcmp(argv[1],"?") == 0)*/ { printf("\n====================代理格式====================\n"); printf("[<protocol>=][<scheme>://]<proxyserver>[:<port>]\n"); printf("eg:\n"); printf("proxyserver:port(默认HTTP代理)\n"); printf("FTP=ftp://proxyserver:port\n"); printf("SOCKS=proxyserver:port\n"); printf("\n================================================\n"); } SetConsoleTextAttribute( (void *)0x7, FOREGROUND_INTENSITY | FOREGROUND_GREEN ); printf("请输入代理地址:(参考代理格式,输入任意字符换行表示不使用代理)\n"); char szProxy[INTERNET_MAX_URL_LENGTH] = {0}; memset(szBuffer, 0, sizeof(szBuffer)); scanf("%s", szBuffer); if (strlen(szBuffer) >= 8) { strcpy(szProxy, szBuffer); } do { printf("请输入测试URL,例如:http://www.baidu.com:80/),输入exit退出,reset重新设置代理\n"); char szUrl[INTERNET_MAX_URL_LENGTH] = {0}; memset(szBuffer, 0, sizeof(szBuffer)); scanf("%s", szBuffer); if (stricmp(szBuffer, "exit") == 0) { flag = 0; break; } if (stricmp(szBuffer, "reset") == 0) { flag = 1; break; } if (strnicmp(szBuffer, "http://", strlen("http://")) != 0) { strcpy(szUrl, "http://"); } strcat(szUrl, szBuffer); DWORD ret = DoInternetProxy(szUrl, szProxy); if (ret) { SetConsoleTextAttribute( (void *)0x7, FOREGROUND_INTENSITY | FOREGROUND_RED ); GetLastErrorMessage(ret, szBuffer, 2048); printf("测试代理完成[%d]%s!\n", ret, szBuffer); SetConsoleTextAttribute( (void *)0x7, FOREGROUND_INTENSITY | FOREGROUND_GREEN ); } else { printf("测试代理完成!\n"); } } while (1); } while (flag); SetStdHandle( STD_OUTPUT_HANDLE, hStdin ); //system("pause"); return 0; }