C 正在尝试从wininet HTTP连接获取套接字
我们有一个通过Web代理实现SSL隧道的遗留应用程序。它使用WininetAPI,多年来在XP上运行良好,但现在在Windows7上失败。我试图分离代码,并制作了一个小程序来重现问题。这是一个用MSVC 9编译的小C程序。见下文 在Windows7上,一旦连接到代理(状态代码200),我就无法从API获取套接字描述符。尽管所有wininet函数都已成功返回且GetLastError()返回0,但我得到的只是一个无效的\u套接字 在XP机器上,一切正常,返回的套接字有效 有人知道吗? 事先非常感谢C 正在尝试从wininet HTTP连接获取套接字,c,sockets,windows-7,wininet,C,Sockets,Windows 7,Wininet,我们有一个通过Web代理实现SSL隧道的遗留应用程序。它使用WininetAPI,多年来在XP上运行良好,但现在在Windows7上失败。我试图分离代码,并制作了一个小程序来重现问题。这是一个用MSVC 9编译的小C程序。见下文 在Windows7上,一旦连接到代理(状态代码200),我就无法从API获取套接字描述符。尽管所有wininet函数都已成功返回且GetLastError()返回0,但我得到的只是一个无效的\u套接字 在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;
}
#包括
#包括
#包括
常量字符*_connect()
{
HINTERNET-hOpen=0;
HINTERNET hConnect=0;
HINTERNET hRequest=0;
int-remotePort=443;
const char*remoteHost=“a.b.c.d”;//不能公开
hOpen=互联网开放(“wininet测试”,互联网开放类型,0,0,0);
如果(!hOpen)返回“InternetOpen”;
hConnect=InternetConnect(hOpen,remoteHost,remotePort,0,0,INTERNET\u服务\u HTTP,0,0);
如果(!hConnect)返回“InternetConnect”;
{
德沃德旗=
互联网\u标志\u缓存\u如果网络\u失败|
互联网\u标志\u忽略\u证书\u CN\u无效|
互联网\u标志\u忽略\u证书\u日期\u无效|
互联网标志保持连接|
互联网\u标志\u无\u缓存\u写入|
互联网标志、布拉格语、NOCACHE|
互联网标志重新加载|
INTERNET\u标志\u重新同步|
互联网安全;
charurl[100];
sprintf(url,“http://%s:%d/”,远程主机,远程端口);
hRequest=HttpOpenRequest(hConnect,“GET”,“connect.html”,“HTTP/1.0”,url,0,标志,0);
如果(!hRequest)返回“HttpOpenRequest”;
}
{
DWORD标志=0;
DWORD bufferLength=sizeof(标志);
if(!InternetQueryOption(hRequest、INTERNET选项、安全标志、标志和缓冲区长度)){
返回“InternetQueryOption”;
}
标志|=(安全标志|忽略|未知| CA |安全标志|忽略|撤销);
如果(!InternetSetOption(hRequest、INTERNET选项、安全标志和标志、sizeof(标志))){
返回“InternetSetOption”;
}
}
如果(!HttpSendRequest(hRequest,0,0,0)){
返回“HttpSendRequest”;
}否则{
字符缓冲区[4];
DWORD bufferSize=sizeof(缓冲区);
if(!HttpQueryInfo(hRequest,HTTP\U查询\U状态\U代码,&buffer,&bufferSize,NULL)){
返回“HttpQueryInfo”;
}否则如果(atoi(缓冲区)!=200){
返回“状态码”;
}
}
{
互联网诊断插座信息idsi;
DWORD bufferSize=sizeof(idsi);
if(!InternetQueryOption(hRequest、INTERNET选项、诊断、套接字信息、idsi和缓冲区大小)){
返回“InternetQueryOption”;
}else if(idsi.Socket==无效的_Socket){
/*在我们的Windows7平台上总是这样,为什么*/
返回“无效套接字”;
}
}
返回0;
}
int main(int argc,常量字符**argv)
{
常量字符*错误=_connect();
如果(错误){
printf(“错误:%s(%d)\n”,错误,GetLastError());
}否则{
printf(“成功”\n);
}
返回0;
}
您确定您的项目不是为unicode编译的吗?如果需要,您需要将char
声明更改为wchar\u t
,并在常量前面加上L
前缀,如:
const wchar_t * pszTmp = L"hello world";
您确定您的项目不是为unicode编译的吗?如果需要,您需要将
char
声明更改为wchar\u t
,并在常量前面加上L
前缀,如:
const wchar_t * pszTmp = L"hello world";
HTTP请求是否使用keep alives?如果不是,那么我的猜测是Win7下的WinInet在接收服务器响应时关闭套接字句柄后使其无效,而XP不会使套接字无效。HTTP请求是否使用keep alives?如果不是,那么我猜Win7下的WinInet在接收到服务器的响应时关闭套接字句柄后会使其无效,而XP不会使套接字无效。 互联网选项诊断插座信息67 检索包含有关指定HTTP请求的数据的INTERNET\u诊断\u套接字\u信息结构。此标志由InternetQueryOption使用 Windows 7:不再支持此选项。 互联网选项诊断插座信息67 检索包含有关指定HTTP请求的数据的INTERNET\u诊断\u套接字\u信息结构。此标志由InternetQueryOption使用
Windows 7:不再支持此选项。设置了标志INTERNET\u标志\u KEEP\u CONNECTION,使用嗅探器,我获得相同的HTTP请求头,其中我有“代理连接:保持活动”。但是,在XP上,TCP连接保持活动状态,但在7上,当SSL握手完成时,客户端发送FIN。你是对的,我得到了一个无效的_套接字,因为TCP连接被终止了,但我不明白为什么在7上是这样,它在XP上保持连接。请求是使用HTTP 1.0还是1.1?如果使用HTTP 1.0,连接的非代理部分是否有
连接:保持活动头?响应的代理连接
和连接
头是否也会说保持活动状态
?请求使用HTTP 1.0。我无法检查是否发送了连接:keep alive
,因为当我查看Wireshark日志时,它似乎是由SSL层加密的。代理响应是HTTP/1.0 200连接已建立,没有返回头。无论客户端是在XP还是在7上运行,HTTP消息都是相同的。然而在7号,在代理响应(状态200)之后,在加密握手之后,我的客户端