WinInet如何使用sock代理
Posted
技术标签:
【中文标题】WinInet如何使用sock代理【英文标题】:WinInet how to use sock proxy 【发布时间】:2017-01-09 02:48:08 【问题描述】:我想使用 WinInet 访问网页,但使用 sock4/sock5 代理。
这是我尝试过的:
HINTERNET hOpen = InternetOpenA(helper.USER_AGENT, INTERNET_OPEN_TYPE_PROXY, ("SOCKS5=200.100.5.1:702", NULL, 0);
这似乎不起作用,我提供了一个无效的 sock 代理,因此当它进行网页连接时它不应该通过,但在我的测试中它正在通过意味着 sock 代理没有被使用但是而是我真正的普通互联网。
我什至还制作了一个辅助函数来在InternetSetOption()
中设置代理:
bool changeProxy(const char* socket)
char strProxyList[MAX_PATH];
bool success = false;
memset(strProxyList, 0, MAX_PATH);
lstrcpyA(strProxyList, "SOCKS5=");
INTERNET_PROXY_INFO proxy;
proxy.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
proxy.lpszProxy = (LPCTSTR)strProxyList;
proxy.lpszProxyBypass = NULL;
if (TRUE == InternetSetOptionA(hOpen, INTERNET_OPTION_PROXY, &proxy, sizeof(INTERNET_PROXY_INFO)))
printf("Socket set to %s\n", socket);
success = true;
else
printf("Failed to set socket to %s\n", socket);
InternetSetOptionA(NULL, INTERNET_OPTION_PROXY_SETTINGS_CHANGED, NULL, 0);
return success;
我尝试在 InternetOpenA()
之后和 InternetConnectA()
函数之前调用此函数,但无论出于何种原因,它都没有使用代理,而是使用我的普通互联网。
这是我的连接代码sn-p:
hConnect = InternetConnectA(hOpen, host, INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, 3, 0, 0);
hRequest = HttpOpenRequestA(hConnect, "POST", uri, NULL, CHECKER_URL, NULL, INTERNET_FLAG_SECURE, 0);
更新:
使用此代码,我能够获得代理集。
但是,由于某种原因,它只允许我设置一次代理,并且在进程运行时不再设置:
HINTERNET hOpen = InternetOpenA(helper.USER_AGENT, 0, NULL, NULL, 0);
INTERNET_PROXY_INFO proxy = 0 ;
proxy.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
proxy.lpszProxy = (LPCTSTR)socket;
proxy.lpszProxyBypass = NULL;
if (UrlMkSetSessionOption(INTERNET_OPTION_PROXY, &proxy, sizeof(proxy), 0) != 0)
success = false;
UrlMkSetSessionOption(INTERNET_OPTION_PROXY_SETTINGS_CHANGED, NULL, 0, 0);
我想在这样做一次后更改代理中间程序,但使用相同的代码第二次更改代理不会生效。
我什至尝试关闭句柄并重新实例化它,但没有成功。
尝试使用时:
InternetSetOptionA(hOpen, INTERNET_OPTION_PER_CONNECTION_OPTION, &proxy, sizeof(INTERNET_PROXY_INFO)))
我得到一个 false 的返回值,所以它不是这样设置的,出于某种原因。但是使用INTERNET_OPTION_PROXY
设置它。
【问题讨论】:
【参考方案1】:要使用 SOCKS 代理,请尝试使用 CERN_PROXY_INTERNET_ACCESS
而不是 INTERNET_OPEN_TYPE_PROXY
。并将SOCKS5=
更改为SOCKS=
。
另外,您的changeProxy()
函数有几个逻辑错误。您从 char[]
到 LPCTSTR
的类型转换是可疑且错误的,而且您实际上并没有在列表中提供任何代理服务器。
【讨论】:
感谢您的提示。如果 InternetOpenA() 函数中的 CERN_PROXY 更改修复了代理设置问题,是否还需要 changeProxy() 函数? @mocode9 我不确定,但你不应该一开始就使用INTERNET_OPTION_PROXY
,而是使用INTERNET_OPTION_PER_CONNECTION_OPTION
。见How to programmatically query and set proxy settings under Internet Explorer。
我让它工作了,但它似乎只更改了一次代理设置。我希望以后能够在我的程序中再次更改它们,以防代理不再存在。但是在第一次更改之后,后续更改似乎没有任何效果。有什么想法吗?
@mocode9: 你用哪个选项来设置它? INTERNET_OPTION_PROXY
应用于静态全局设置,而 INTERNET_OPTION_PER_CONNECTION_OPTION
必须应用于您打开的每个 HINTERNET
句柄。请edit your question显示您的最新代码。
您不能为不同的连接重复使用 WinInet 句柄,并且切换代理需要建立新的连接。这并不是真正的 WinInet 限制。即使你掉到 TCP 层,手动实现 SOCKS 和 HTTP(S),你仍然做不到。您可以在 HTTP 请求之间切换代理,但不能通过同一连接,您必须先断开现有连接。以上是关于WinInet如何使用sock代理的主要内容,如果未能解决你的问题,请参考以下文章