繁体   English   中英

C ++ WinInet InternetCloseHandle崩溃

[英]C++ WinInet InternetCloseHandle crash

我写了一个使用WinInet库的程序。 该程序每天运行约8-12小时。 首先,它连接到Internet,然后使用FTP下载/上传文件。 之后,它将启动一个循环,该循环在不同的时间间隔内启动多达两个线程。 两个线程都对同一服务器执行GET -requests,看起来像这样:

private void Thread()
{
    if(!InternetGetConnectedState(NULL, NULL))
    {
        connectToInternet();
    }

    // some code...

    HINTERNET httpOpenRequest = HttpOpenRequest(
        hHTTPConnection,        // InternetConnect-Handle
        L"GET",                 // HTTP-Verb
        request_target,         // FileName
        L"HTTP/1.1",            // HTTP-Version
        NULL,                   // Referer
        NULL,                   // AcceptTypes
        INTERNET_FLAG_RELOAD,   // Flags
        0                       // Context
        );

    BOOL httpsRequest = HttpSendRequest(
            httpOpenRequest,    // Handle of HttpOpenRequest
            NULL,               // Headers
            0,                  // Headers-Length
            NULL,               // Optional
            0                   // Optional-Length
            );

    InternetCloseHandle(httpOpenRequest); // App-Crash sometimes here!
}

我的connectToInternet功能在这里:

int connectToInternet()
{
    DWORD InetTest1 = 16000;
    while (InetTest1 != 0)
    {
        InetTest1 = InternetAttemptConnect(0);
        // wait 1 second for next attempt
        if (InetTest1 != 0)
        {
            Sleep(1000);
        }
    }

    BOOL InetTest2 = FALSE;
    while (!InetTest2)
    {
        InetTest2 = InternetCheckConnection(
            L"http://www.example.com",  // URL
            FLAG_ICC_FORCE_CONNECTION,  // Flags
            0                           // Reserved
            );
        // wait 1 second for next attempt
        if (!InetTest2)
        {
            Sleep(1000);
        }
    }

    while (hInternetOpen == NULL)
    {
        hInternetOpen = InternetOpen(
            L"Custom-Agent",            // Agent
            INTERNET_OPEN_TYPE_DIRECT,  // AccessType
            NULL,                       // ProxyName
            NULL,                       // ProxyBypass
            0                           // Flags
            );

        // wait 1 second for next attempt
        if (hInternetOpen == NULL)
        {
            Sleep(1000);
        }
    }

    while (hHTTPConnection == NULL)
    {
        hHTTPConnection = InternetConnect(
            hInternetOpen,              // InternetOpen-Handle
            L"www.example.com",         // ServerName
            INTERNET_DEFAULT_HTTP_PORT, // ServerPort
            NULL,                       // Username
            NULL,                       // Password
            INTERNET_SERVICE_HTTP,      // Service
            0,                          // Flags
            0                           // Context
            );

        // wait 1 second for next attempt
        if (hHTTPConnection == NULL)
        {
            Sleep(1000);
        }
    }

    return 0;
}

(我在这里找到此功能的基本工作流程: https : //msdn.microsoft.com/zh-cn/library/windows/desktop/aa383996(v=vs.85 ) .aspx


现在的问题:

问题1:当两个线程之一调用InternetCloseHandle(httpOpenRequest)时,似乎很少遇到应用崩溃的情况。 我找不到这些应用程序崩溃的原因...您有任何想法吗?

问题2:运行程序的笔记本电脑似乎存在Internet连接问题,因为它经常断开连接几秒钟到几分钟甚至几小时。 因此,如果InternetGetConnectedState(NULL, NULL)false ,那么我将首先在两个线程中调用connectToInternet() 这是必需步骤吗,或者如果我不调用connect函数,它也可以工作吗? 如果连接断开,全局HINTERNET -Handles是否无效?

[EDIT]同时,我怀疑我的程序导致了连接问题,因为我家里的有线网络也没有互联网访问权限! 我有什么错误吗?

看来我的问题是由多个线程同时运行并尝试调用InternetCloseHandle()

同时,我重写了代码。 我还试图让雷米·勒博发表评论。 我的代码现在看起来像以下示例:

void Thread()
{
    // access-control
    if (ThreadRunning == true)
    {
        return 99;
    }
    ThreadRunning = true;

    // variables
    HINTERNET hInternetOpen = NULL;
    HINTERNET hHTTPConnection = NULL;
    HINTERNET httpOpenRequest = NULL;
    int connectionAttempts;
    string target_string;
    wstring target_wstring;
    LPCWSTR request_target;
    BOOL httpSendRequestSuccessful;
    BOOL httpQueryInfoReceived;
    DWORD statusCode = 0;
    DWORD statusCodeLen = sizeof(statusCode);
    BOOL dataAvailable;
    DWORD numberOfBytesAvailable;
    BOOL internetReadFileSuccessful;
    char buffer[4096] = { "" };
    DWORD numberOfBytesRead;

    // Connect to Internet
    connectionAttempts = 0;
    DWORD InetTest1 = 16000;
    while (InetTest1 != 0)
    {
        InetTest1 = InternetAttemptConnect(0);
        if (InetTest1 != 0)
        {
            connectionAttempts++;
            // prevent an infinite loop
            if (connectionAttempts >= 5)
            {
                // reset access-control
                ThreadRunning = false;

                return 1;
            }
            // wait 1 second if it fails
            Sleep(1000);
        }
    }

    // reset connectionAttempts
    connectionAttempts = 0;
    BOOL InetTest2 = FALSE;
    while (!InetTest2)
    {
        InetTest2 = InternetCheckConnection(
            L"http://www.example.com",  // URL
            FLAG_ICC_FORCE_CONNECTION,  // Flags
            0                           // Reserved
            );
        if (InetTest2 == FALSE)
        {
            connectionAttempts++;
            // prevent an infinite loop
            if (connectionAttempts >= 5)
            {
                // reset access-control
                ThreadRunning = false;

                return 2;
            }
            // wait 1 second if it fails
            Sleep(1000);
        }
    }

    // reset connectionAttempts
    connectionAttempts = 0;
    while (hInternetOpen == NULL)
    {
        hInternetOpen = InternetOpen(
            L"Custom-Agent",                // Agent
            INTERNET_OPEN_TYPE_DIRECT,      // AccessType
            NULL,                           // ProxyName
            NULL,                           // ProxyBypass
            0                               // Flags
            );

        if (hInternetOpen == NULL)
        {
            connectionAttempts++;
            // prevent an infinite loop
            if (connectionAttempts >= 5)
            {
                // reset access-control
                ThreadRunning = false;

                return 3;
            }
            // wait 1 second if it fails
            Sleep(1000);
        }
    }

    // reset connectionAttempts
    connectionAttempts = 0;
    while (hHTTPConnection == NULL)
    {
        hHTTPConnection = InternetConnect(
            hInternetOpen,              // InternetOpen-Handle
            L"www.example.com",         // ServerName
            INTERNET_DEFAULT_HTTP_PORT, // ServerPort
            NULL,                       // Username
            NULL,                       // Password
            INTERNET_SERVICE_HTTP,      // Service
            0,                          // Flags
            0                           // Context
            );
        if (hHTTPConnection == NULL)
        {
            connectionAttempts++;
            // prevent an infinite loop
            if (connectionAttempts >= 5)
            {
                // reset access-control
                onlineSettingsThreadRunning = false;

                // Handle-Cleanup
                InternetCloseHandle(hInternetOpen);

                return 4;
            }
            // wait 1 second if it fails
            Sleep(1000);
        }
    }

    // some code...

    // open HTTP-Request
    httpOpenRequest = HttpOpenRequest(
        hHTTPConnection,        // InternetConnect-Handle
        L"GET",                 // HTTP-Verb (GET or POST)
        request_target,         // FileName
        L"HTTP/1.1",            // HTTP-Version
        NULL,                   // Referer
        NULL,                   // AcceptTypes
        INTERNET_FLAG_RELOAD,   // Flags
        0                       // Context
        );
    if (httpOpenRequest == NULL)
    {
        // Handle-Cleanup
        InternetCloseHandle(hHTTPConnection);
        InternetCloseHandle(hInternetOpen);

        // reset access-control
        onlineSettingsThreadRunning = false;

        return 5;
    }

    // send HTTP-Request
    httpSendRequestSuccessful = HttpSendRequest(
        httpOpenRequest,    // Handle von HttpOpenRequest
        NULL,               // Headers
        0,                  // Headers-Length
        NULL,               // Optional
        0                   // Optional-Length
        );
    if (httpSendRequestSuccessful == FALSE)
    {
        // Handle-CleanUp
        InternetCloseHandle(httpOpenRequest);
        InternetCloseHandle(hHTTPConnection);
        InternetCloseHandle(hInternetOpen);

        // reset access-control
        onlineSettingsThreadRunning = false;

        return 6;
    }

    // read Server-Status
    httpQueryInfoReceived = HttpQueryInfo(
        httpOpenRequest,
        HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
        &statusCode,
        &statusCodeLen,
        NULL
        );
    if (httpQueryInfoReceived == FALSE || statusCode != 200)
    {
        // Handle-CleanUp
        InternetCloseHandle(httpOpenRequest);
        InternetCloseHandle(hHTTPConnection);
        InternetCloseHandle(hInternetOpen);

        // reset access-control
        onlineSettingsThreadRunning = false;

        return 7;
    }

    // test, how much bytes are readable
    dataAvailable = InternetQueryDataAvailable(
        httpOpenRequest,
        &numberOfBytesAvailable,
        0,
        0
        );
    if (dataAvailable == FALSE)
    {
        // Handle-CleanUp
        InternetCloseHandle(httpOpenRequest);
        InternetCloseHandle(hHTTPConnection);
        InternetCloseHandle(hInternetOpen);

        // reset access-control
        onlineSettingsThreadRunning = false;

        return 8;
    }

    // some code...

    // Close internet-connection
    InternetCloseHandle(httpOpenRequest);
    InternetCloseHandle(hHTTPConnection);
    InternetCloseHandle(hInternetOpen);

    // reset access-control
    ThreadRunning = false;

    return 0;
}

因此,我的connectToInternet()函数不再存在。 现在,它是每个需要Internet访问的线程的一部分。 它还不再使用GetLastError()因为这可能会传递错误的结果...

我仍在测试我的代码,但它似乎很有希望:-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM