【问题标题】:recv function blocks with keep-alive (HTTP)具有 keep-alive (HTTP) 的 recv 功能块
【发布时间】:2015-09-22 07:13:12
【问题描述】:

我正在学习 Windows 中的套接字,以及 HTTP 协议。 所以我用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);

    ....
}

我想知道如何解决这个问题或者什么是使用keep-alive的正确方法。

【问题讨论】:

  • @nos 我已经读过,使用 keep-alive 我可以进行多次读取/接收调用,而且,我只是在测试/学习。我在recv之前和之后设置了一个断点。
  • recv 调用结束后RecvBuffer 中有什么内容?
  • 您发送的数据比您在Content-Length: 中宣布的要多。数据不应以\r\n\r\n 结尾。不确定服务器是否会忽略此错误。也许它等待另一个请求只是因为你输入了keep-alive
  • 请调查@ElderBug 的评论。如果您设置了Content-Length,那么服务器会期望您正确设置。
  • @ElderBug 谢谢!我解决了这个问题并解决了我的问题

标签: c++ c sockets http winapi


【解决方案1】:

在您的 HTTP 请求中,您发送了一个额外的 \r\n\r\n,但您未将其包含在您的 Content-Length 中,因此数据和宣布的长度不匹配。 HTTP 标准说:

当在消息正文中给出 Content-Length 时 允许,其字段值必须与 消息体。

MUST 很重要,这意味着服务器完全有权拒绝您的请求。您指定keep-alive 的事实也可能意味着服务器等待下一个有效请求。由于您只发送 4 个字节,因此服务器最终会在 5 秒后关闭连接,并且可能会发送错误(这部分只是对实际发生的情况的推测)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 2015-06-08
    • 2014-01-12
    相关资源
    最近更新 更多