C ++ CInternetSession连接丢失

时间:2018-02-05 10:20:40

标签: c++ timeout

我使用CInternetSession来获取和发布请求。但是当connexion超时发生时,我丢失了connexion并且我总是得到无效的服务器请求错误,我不明白为什么。此外,还有内存泄漏。

#include "stdafx.h"
#include "httpConnexion.h"
#include "TSException.h"

ChttpConnexion::ChttpConnexion()
    : CInternetSession(AfxGetAppName(), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL, INTERNET_FLAG_DONT_CACHE)
    , m_lastRequest()
{       
    SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 10000);
    SetOption(INTERNET_OPTION_RECEIVE_TIMEOUT, 10000);
    m_bAttente = true;
}

ChttpConnexion::~ChttpConnexion()
{
}

std::string ChttpConnexion::sendRequest(const std::string& strUrl)
{   
    DWORD dwServiceType;
    CString strServerName;
    CString strObject;
    INTERNET_PORT nPort;
    AfxParseURL(strUrl.c_str(), dwServiceType, strServerName, strObject, nPort);

    CString strHeaders = _T("User-Agent: User-Agent=Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7\r\nConnection: keep-alive\r\nContent-Type: application/x-www-form-urlencoded");
    CString strTmp = "", strResult = "";
    CHttpConnection* pHttpConnexion = NULL;
    CHttpFile* pHttpFile = NULL;

    try
    {   
        //Creation de la connexion Http
        pHttpConnexion = GetHttpConnection(strServerName, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, nPort, NULL, NULL);

        //Creation de la requete GET
        pHttpFile = pHttpConnexion->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject, NULL, 1, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE);

        //Envoi de la requéte
        BOOL bRequestSend = pHttpFile->SendRequest(strHeaders);

        CString headers;headers.Empty();
        DWORD dwRet;
        pHttpFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF,headers);
        pHttpFile->QueryInfoStatusCode(dwRet);

        //Lecture du résultat
        while ( pHttpFile->ReadString(strTmp))
        {
            strResult += strTmp;
        }

        //Fermeture de la requéte
        pHttpFile->Close();

        //Fermeture de la connexion
        pHttpConnexion->Close();

        //Suppression des objets
        if (pHttpFile != NULL)  
            delete pHttpFile;

        if (pHttpConnexion != NULL) 
            delete pHttpConnexion;
    }
    catch(CInternetException* exp)
    {
        exp->Delete();

        //Fermeture de la requéte
        if (pHttpFile != NULL)
        {
            pHttpFile->Close();
            delete pHttpFile;
        }

        //Fermeture de la connexion
        if (pHttpConnexion != NULL) 
        {
            pHttpConnexion->Close();
            delete pHttpConnexion;
        }
        throw CTSException("sendRequest");
    }       
    return strResult.GetString();
}


std::string ChttpConnexion::postRequest(const std::string& strUrl, const std::string& postData)
{    
    DWORD dwServiceType;
    CString strServerName;
    CString strObject;
    INTERNET_PORT nPort;
    AfxParseURL(strUrl.c_str(), dwServiceType, strServerName, strObject, nPort);

    CString strHeaders = _T("User-Agent: User-Agent=Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7\r\nConnection: keep-alive\r\nContent-Type: application/x-www-form-urlencoded");
    CString strTmp = "", strResult = "";
    CHttpConnection* pHttpConnexion = NULL;
    CHttpFile* pHttpFile = NULL;

    try
    {   
        //Creation de la connexion Http
        pHttpConnexion = GetHttpConnection(strServerName, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, nPort, NULL, NULL);

        //Creation de la requete GET
        pHttpFile = pHttpConnexion->OpenRequest(CHttpConnection::HTTP_VERB_POST, strObject, NULL, 1, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE);

        //Envoi de la requéte

        BOOL bRequestSend = pHttpFile->SendRequest(strHeaders, (LPVOID) (LPCTSTR) postData.c_str(), postData.length());

        CString headers;headers.Empty();
        DWORD dwRet;
        pHttpFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF,headers);
        pHttpFile->QueryInfoStatusCode(dwRet);

        CString data;
        GetCookie(strServerName, "sess_id", data);

        //Lecture du résultat
        while ( pHttpFile->ReadString(strTmp))
        {
            strResult += strTmp;
        }


        //Fermeture de la requéte
        pHttpFile->Close();

        //Fermeture de la connexion
        pHttpConnexion->Close();

        //Suppression des objets
        if (pHttpFile != NULL)  
            delete pHttpFile;

        if (pHttpConnexion != NULL) 
            delete pHttpConnexion;
    }
    catch(CInternetException* exp)
    {
        exp->Delete();

        //Fermeture de la requéte
        if (pHttpFile != NULL)
        {
            pHttpFile->Close();
            delete pHttpFile;
        }

        //Fermeture de la connexion
        if (pHttpConnexion != NULL) 
        {
            pHttpConnexion->Close();
            delete pHttpConnexion;
        }
        throw CTSException("postRequest");
    }   

    return strResult.GetString();
}

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

  • 当您构造对象并调用CInternetSession构造函数时,为什么第3个参数为NULL?它应该是PRE_CONFIG_INTERNET_ACCESS之类的东西。如果您在代理服务器后面,则可能需要使用代理设置。
  • 检查strServerName的内容,可能无效,GetHttpConnection因此失败。
  • 在您的tryGetHttpConnectionOpenRequest,但您不会检查结果是否为空。如果它们不是NULL以便删除它们,您只能稍后检查(太晚)。在使用GetHttpConnectionOpenRequest之前,您应该先检查它们。 (但我猜这个例外发生在GetHttpConnection
  • 期间
  • 如果在10秒后发生超时,可能是因为你的超时时间太短(在你的构造函数中)。
  • 有一些旧报告称https可能存在问题。但你没有提到你的要求是什么以及你要求的是什么。
  • 在您的请求标头中,您正在请求不同的文件格式(xml,html,png等等),但您使用的是GetString并将其附加到字符串中。如果您获得二进制数据,它可能无法正常工作。你应该使用char []缓冲区。 Check this example.
  • 在使用您的对象ChttpConnexion后,您是否在其上调用了.Close()

最后,我建议附加一个调试器并在catch中放置一个断点,以查看错误发生的确切位置,或者添加一些调试日志。这可能会有所帮助。