winhttpsendrequest подключается, но что-то немедленно отправляет fin ack - PullRequest
0 голосов
/ 21 июня 2020

У меня есть локальный сервер, прослушивающий порт 2101. Я могу подключиться к нему и получить данные с помощью браузера. Авторизация не требуется. Я использую API Winhttp, но похоже, что что-то заставляет клиента отправлять запрос сразу после успешного установления TCP-соединения. Я сравнил записи Wireshark для случаев приложения браузера и winhttp, и я вижу практически одинаковые заголовки в обоих случаях, и TCP-соединение успешно установлено в обоих случаях (SYN, SYN ACK, ACK), и соединение не закрывается в случае браузера. но это в случае winhttp. Вот код winhttp. При пошаговом выполнении кода моего приложения кажется, что и открытие, и закрытие происходят к тому времени, когда я перехожу через вызов winhttpsendrequest.

#include <windows.h>
#include <winhttp.h>
#include <iostream>
using namespace std;

int main() {
    DWORD dwSize = 0;
    DWORD dwDownloaded = 0;
    LPSTR pszOutBuffer;
    BOOL  bResults = FALSE;
    DWORD statusCode = 0;
    DWORD statusCodeSize = sizeof(DWORD);
    HINTERNET hSession = NULL,
        hConnect = NULL,
        hRequest = NULL;

    // Use WinHttpOpen to obtain a session handle.
    hSession = WinHttpOpen(L"test data client",
        WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY,
        WINHTTP_NO_PROXY_NAME,
        WINHTTP_NO_PROXY_BYPASS, 0); // same result with default or no proxy

    // Specify an HTTP server.
    if (hSession)
    {
        // WinHttpSetTimeouts(hSession, 0 /*dwResolveTimeout*/, 60000 /*dwConnectTimeout*/, 120000 /*dwSendTimeout*/, 120000 /*dwReceiveTimeout*/); // same result with or without this call
        hConnect = WinHttpConnect(hSession, L"127.0.0.1", 2101, 0);
    }

    const wchar_t* types[] = { L"application/octet-stream", NULL };

    // Create an HTTP Request handle.
    if (hConnect)
        hRequest = WinHttpOpenRequest(hConnect, L"GET",
            L"/test_source",
            //L"HTTP/1.0", WINHTTP_NO_REFERER,
            nullptr, WINHTTP_NO_REFERER,
            //types,
            WINHTTP_DEFAULT_ACCEPT_TYPES,
            0);

    //const wchar_t* headers = L"Accept:*/*\r\nAccept-Encoding: gzip, deflate, br\r\nX-P2P-PeerDist:\r\nX-P2P-PeerDistEx:\r\nUpgrade-Insecure-Requests:1\r\nConnection:keep-alive";

    /*if (hRequest)
        bResults = WinHttpAddRequestHeaders(hRequest,
            headers,
            (ULONG)-1L,
            WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);*/

    // Send a Request.
    if (hRequest)
        bResults = WinHttpSendRequest(hRequest,
            WINHTTP_NO_ADDITIONAL_HEADERS,
            0, WINHTTP_NO_REQUEST_DATA, 0,
            0, 0);

    if (bResults)
        bResults = WinHttpQueryHeaders(hRequest,
            WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
            WINHTTP_HEADER_NAME_BY_INDEX,
            &statusCode,
            &statusCodeSize,
            WINHTTP_NO_HEADER_INDEX);  // This call and all others return errors

    if(!bResults)
    {
        printf("Error %u in WinHttpQueryHeaders.\n",
            GetLastError());  // getlasterror returns 12019
    }

    if (bResults)
        bResults = WinHttpReceiveResponse(hRequest, NULL);

    if (bResults)
    {
        do
        {
            // Check for available data.
            dwSize = 0;
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
            {
                printf("Error %u in WinHttpQueryDataAvailable.\n",
                    GetLastError());
                break;
            }

            // No more available data.
            if (!dwSize)
                break;

            // Allocate space for the buffer.
            pszOutBuffer = new char[dwSize + 1];
            if (!pszOutBuffer)
            {
                printf("Out of memory\n");
                break;
            }

            // Read the Data.
            ZeroMemory(pszOutBuffer, dwSize + 1);

            if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,
                dwSize, &dwDownloaded))
            {
                printf("Error %u in WinHttpReadData.\n", GetLastError());
            }
            else
            {
                printf("%s", pszOutBuffer);
            }

            // Free the memory allocated to the buffer.
            delete[] pszOutBuffer;

            // This condition should never be reached since WinHttpQueryDataAvailable
            // reported that there are bits to read.
            if (!dwDownloaded)
                break;

        } while (dwSize >= 0);
    }
    else
    {
        // Report any errors.
        printf("Error %d has occurred.\n", GetLastError());
    }

    // Close open handles.
    if (hRequest) WinHttpCloseHandle(hRequest);
    if (hConnect) WinHttpCloseHandle(hConnect);
    if (hSession) WinHttpCloseHandle(hSession);

}

...