简体   繁体   中英

recv function blocks with keep-alive (HTTP)

I'm learning about sockets in Windows, also HTTP protocol. So I was doing some tests with keep-alive but for some reason recv hangs for about 5 seconds, here it's:

VOID TestWinsock()
{
    WSADATA WsaData;
    addrinfo hints;
    addrinfo* hResult;
    SOCKET hsocket;
    int Result;

    WSAStartup(MAKEWORD(2, 2), &WsaData);
    RtlZeroMemory(&hints, sizeof(hints));

    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    Result = getaddrinfo("localhost", "80", &hints, &hResult);
    if (Result != 0)
    {
        return;
    }

    hsocket = socket(hResult->ai_family, hResult->ai_socktype, hResult->ai_protocol);
    if (hsocket == INVALID_SOCKET)
    {
        return;
    }

    Result = connect(hsocket, hResult->ai_addr, (int)hResult->ai_addrlen);
    if (Result == SOCKET_ERROR)
    {
        return;
    }

    char* POSTContent;
    char HTTPRequestBuffer[1024];
    char RecvBuffer[1024];

    char* HTTPRequest =
        "POST %s HTTP/1.0\r\n"
        "Host: %s\r\n"
        "connection: keep-alive\r\n"
        "Content-type: application/x-www-form-urlencoded\r\n"
        "Content-Length: %u\r\n"
        "\r\n"
        "%s"
        "\r\n"
        "\r\n";

    POSTContent = "variable1=10";
    wsprintfA(
        HTTPRequestBuffer,
        HTTPRequest,
        "/tests/test.php",
        "127.0.0.1",
        strlen(POSTContent),
        POSTContent
        );

    int sent = send(hsocket, HTTPRequestBuffer, strlen(HTTPRequestBuffer), 0);
    RtlZeroMemory(RecvBuffer, sizeof(RecvBuffer));

    // here recv blocks for about 5 seconds, yeah, it reads only 100 bytes, tried with something like sizeof(RecvBuffer) as well.
    recv(hsocket, RecvBuffer, 100, 0);

    ....
}

I want to know how to solve this problem or which is the proper way to use keep-alive.

In your HTTP request, you send an additional \\r\\n\\r\\n which you do not include in your Content-Length , thus the data and and the length announced does not match. The HTTP standard says that :

When a Content-Length is given in a message where a message-body is allowed, its field value MUST exactly match the number of OCTETs in the message-body.

The MUST is important, it means the server is totally in its right to reject your request. The fact that you specified keep-alive can also mean that the server waits for a next, valid request. Since you only send 4 bytes, the server end up closing the connection anyway after 5s, and probably sends an error (this part is only speculation about what actually happens).

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