简体   繁体   English

具有保持活动状态(HTTP)的recv功能块

[英]recv function blocks with keep-alive (HTTP)

I'm learning about sockets in Windows, also HTTP protocol. 我正在学习Windows中的套接字以及HTTP协议。 So I was doing some tests with keep-alive but for some reason recv hangs for about 5 seconds, here it's: 因此,我正在使用keep-alive做一些测试,但是由于某种原因recv挂起了大约5秒钟,这是:

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. 在您的HTTP请求中,您发送了一个额外的\\r\\n\\r\\n ,您没有将其包含在Content-Length ,因此数据和声明的长度不匹配。 The HTTP standard says that : HTTP标准说:

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. 当在允许消息正文的消息中给出Content-Length时,其字段值务必与消息正文中的OCTET数量完全匹配。

The MUST is important, it means the server is totally in its right to reject your request. MUST非常重要,这意味着服务器完全有权拒绝您的请求。 The fact that you specified keep-alive can also mean that the server waits for a next, valid request. 您指定keep-alive的事实也可能意味着服务器等待下一个有效请求。 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). 由于仅发送4个字节,因此服务器最终将在5s之后关闭连接,并且可能发送错误(这只是推测实际发生的情况)。

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

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