【发布时间】:2011-12-24 16:46:23
【问题描述】:
我们有一个旧版应用程序,它通过 Web 代理实现 SSL 隧道。它使用 wininet API,并且在 XP 上运行良好多年,但现在在 Windows 7 上失败了。我尝试隔离代码并制作了一个小程序来重现该问题。这是一个用 MSVC 9 编译的小型 C 程序。见下文。
在 Windows 7 上,一旦连接到代理(状态代码 200),我就无法从 API 获取套接字描述符。我得到的只是一个 INVALID_SOCKET,即使所有 wininet 函数都成功返回并且 GetLastError() 返回 0。
在 XP 机器上,一切正常,返回的套接字是有效的。
有人知道吗? 非常感谢您。
#include <windows.h>
#include <wininet.h>
#include <stdio.h>
const char *_connect()
{
HINTERNET hOpen = 0;
HINTERNET hConnect = 0;
HINTERNET hRequest = 0;
int remotePort = 443;
const char *remoteHost = "a.b.c.d"; // Cannot disclose
hOpen = InternetOpen("wininet-test", INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
if (!hOpen) return "InternetOpen";
hConnect = InternetConnect(hOpen, remoteHost, remotePort, 0, 0, INTERNET_SERVICE_HTTP, 0, 0);
if (!hConnect) return "InternetConnect";
{
DWORD flags =
INTERNET_FLAG_CACHE_IF_NET_FAIL |
INTERNET_FLAG_IGNORE_CERT_CN_INVALID |
INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
INTERNET_FLAG_KEEP_CONNECTION |
INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_PRAGMA_NOCACHE |
INTERNET_FLAG_RELOAD |
INTERNET_FLAG_RESYNCHRONIZE |
INTERNET_FLAG_SECURE;
char url[100];
sprintf(url, "http://%s:%d/", remoteHost, remotePort);
hRequest = HttpOpenRequest(hConnect, "GET", "connect.html", "HTTP/1.0", url, 0, flags, 0);
if (!hRequest) return "HttpOpenRequest";
}
{
DWORD flags=0;
DWORD bufferLength = sizeof(flags);
if (!InternetQueryOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS, &flags, &bufferLength)) {
return "InternetQueryOption";
}
flags |= (SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_REVOCATION);
if (!InternetSetOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS, &flags, sizeof(flags))) {
return "InternetSetOption";
}
}
if (!HttpSendRequest(hRequest, 0, 0, 0, 0)) {
return "HttpSendRequest";
} else {
char buffer[4];
DWORD bufferSize = sizeof(buffer);
if (!HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE, &buffer, &bufferSize, NULL)) {
return "HttpQueryInfo";
} else if (atoi(buffer) != 200) {
return "status code";
}
}
{
INTERNET_DIAGNOSTIC_SOCKET_INFO idsi;
DWORD bufferSize = sizeof(idsi);
if (!InternetQueryOption(hRequest, INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO, &idsi, &bufferSize)) {
return "InternetQueryOption";
} else if (idsi.Socket == INVALID_SOCKET) {
/* This is always the case on our Windows 7 platform, why? */
return "invalid socket";
}
}
return 0;
}
int main(int argc, const char **argv)
{
const char *error = _connect();
if (error) {
printf("ERROR: %s (%d)\n", error, GetLastError());
} else {
printf("SUCCESS\n");
}
return 0;
}
【问题讨论】:
标签: c sockets windows-7 wininet