在 C++ 中使用 wininet

Posted

技术标签:

【中文标题】在 C++ 中使用 wininet【英文标题】:using wininet in C++ 【发布时间】:2011-04-11 14:19:35 【问题描述】:

我有一个服务器,如果我发送它“https://MyDomain/Dir1/Dir2/login.html?u=1234&t=5678”将响应一个 xml 文档。有谁知道我如何在 wininet 中做到这一点?

这是我到目前为止所做的:

std::string GetLoginData(void)

    HINTERNET hInternet, hConnection, hRequest;
    std::string retVal;

    hInternet = InternetOpen(L"My Application", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    if(NULL != hInternet)
    
        hConnection = InternetConnect(hInternet, L"MyDomain", INTERNET_DEFAULT_HTTPS_PORT, L"", L"", INTERNET_SERVICE_HTTP, 0, NULL);
        if(NULL != hConnection)
        
            const wchar_t* lplpszAcceptTypes[] = L"text/xml", L"application/xml", L"application/xhtml+xml", NULL;

            hRequest = HttpOpenRequest(hConnection, L"GET", L"Dir1/Dir2/Login.html", NULL, NULL, lplpszAcceptTypes,
                INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
                INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | INTERNET_FLAG_KEEP_CONNECTION |
                INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_UI | INTERNET_FLAG_PRAGMA_NOCACHE, 0);
            if(NULL != hRequest)
            
                const char Params[] = "u=1234&t=5678";

                BOOL rc = HttpSendRequest(hRequest, NULL, 0, (void*)Params, strlen(Params));

                if(rc) // here rc = 0 and GetLastError() returns 12152
                
                    DWORD availDataLen;
                    char Buff[4096];
                    DWORD readCount = ERROR_INTERNET_CONNECTION_RESET;

                    InternetQueryDataAvailable(hInternet, &availDataLen, 0, 0);
                    while(0 < availDataLen)
                    
                        InternetReadFile(hInternet, Buff, min(sizeof(Buff), availDataLen), &readCount);
                        availDataLen -= readCount;
                        retVal = retVal + Buff;
                    
                
                InternetCloseHandle(hRequest);
            
            InternetCloseHandle(hConnection);
        
        InternetCloseHandle(hInternet);
    
    return retVal;

但正如您在代码中看到的那样,HttpSendRequest() 失败,GetLastError() 返回 12152

提前谢谢你 山姆

【问题讨论】:

【参考方案1】:

那是 ERROR_WINHTTP_INVALID_SERVER_RESPONSE。最好的猜测是您在 HTTPS 端口上发出 HTTP 请求。

我不太了解 API,但您似乎需要将 INTERNET_FLAG_SECURE 添加到您的 HttpOpenRequest 调用和/或您的 InternetConnect 调用的 flags 参数中:

INTERNET_FLAG_SECURE 使用安全事务语义。这转化为使用安全套接字层/私有通信技术 (SSL/PCT),并且仅在 HTTP 请求中有意义。该标志由 HttpOpenRequest 和 InternetOpenUrl 使用,但如果 URL 中出现 https://,则这是多余的。InternetConnect 函数使用此标志进行 HTTP 连接;在此连接下创建的所有请求句柄都将继承此标志。

【讨论】:

【参考方案2】:

INTERNET_FLAG_SECURE 添加到HttpOpenRequest 对我有用。

HINTERNET hHttpRequest = HttpOpenRequest(hHttpSession, lpszVerb, lpszObjectName, 0, 0, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE, 0);

【讨论】:

以上是关于在 C++ 中使用 wininet的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Visual C++ 2010 中使用 C++ 库 [重复]

我们啥时候需要在纯 C++ 程序中使用结构?纯 C++ 程序是不是需要结构? [复制]

当python使用“Python.h”调用该c++进程时,如何在python中停止一个c++进程

在 Objective-C 中使用外部 C++ 头文件

使用多个视图在 QML 中查看、编辑和更新数据(来自 C++),而数据保留在 C++ 中(订阅数据)

在 c++ 应用程序中使用 Simulink