简体   繁体   中英

C++ WinInet InternetCloseHandle crash

I wrote a program which uses WinInet-library. The program runs for about 8-12 hours a day. At first it connects to the internet, then it uses FTP to down-/up-load files. After that it starts a loop, which starts up to two threads in different time intervals. Both threads are doing GET -requests to the same server and are looking like this:

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!
}

my connectToInternet -function is here:

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;
}

(the basic workflow for this function I found here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383996(v=vs.85).aspx )


Now the questions:

Q1: It seems that I rarely get app-crashes when one of the two threads calls InternetCloseHandle(httpOpenRequest) . I can't find the reason for these app crashes... Do you have any Ideas?

Q2: The laptop, where the programm is running seems to have internet-connectivity issues because it looses connection for some seconds to some minutes or even hours very often. Therefore I call connectToInternet() in both Threads first, if InternetGetConnectedState(NULL, NULL) is false . Is this step required, or would it also work if I wouldn't make a call to the connect-function? Are the global HINTERNET -Handles invalid if the connection breaks?

[EDIT] in the meanwhile I'm suspecting my program for causing the connectivity-problems because I also had no internet-access on my wired-network at home! Is there any mistake I'm making?

It seems that my problem was caused by multiple threads running at the same time and trying to call InternetCloseHandle() .

In the meanwhile I rewrote my code. I also tried to involve Remy Lebeau 's comments. My code looks like the following examples now:

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;
}

So my connectToInternet() -function does not exist any more. It is now part in each Thread which needs internet-access. It also does not use GetLastError() any more as this could deliver wrong results...

I'm still testing my code but it seems to be promising :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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