c++ - Bug 保活延迟

标签 c++ sockets keep-alive

这段代码使用 keep-alive 连接来加载许多共享相同 IP 地址的域,但是在前 25 个域之后有一个错误,每个域加载都有 30 秒的延迟!如何解决?

#pragma comment(lib,"ws2_32.lib")
#include <WinSock2.h>
#include <iostream>
int main(){
    WSAData wsaData;
    WORD DllVersion = MAKEWORD(2, 1);
    if (WSAStartup(DllVersion, &wsaData) != 0) {
        MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);
        exit(1);
    }
    SOCKADDR_IN addr;
    int sizeofaddr = sizeof(addr);
    addr.sin_addr.s_addr = inet_addr("123.123.123.123");
    addr.sin_port = htons(80);
    addr.sin_family = AF_INET;
    SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL);
    if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0)
    {
        MessageBoxA(NULL, "Failed to Connect", "Error", MB_OK | MB_ICONERROR);
        return 0;
    }
    std::cout << "Connected!" << std::endl;
    char MTD[] = "GET / HTTP/1.1\r\nHost:site.com\r\nConnection:keep-alive\r\n\r\nGET / HTTP/1.1\r\nHost:site.com\r\nConnection:keep-alive\r\n\r\nGET / HTTP/1.1\r\nHost:site.com\r\nConnection:keep-alive\r\n\r\nGET / HTTP/1.1\r\nHost:site.com\r\nConnection:keep-alive\r\n\r\nGET / HTTP/1.1\r\nHost:site.com\r\nConnection:keep-alive\r\n\r\nGET / HTTP/1.1\r\nHost:site.com\r\nConnection:keep-alive\r\n\r\nGET / HTTP/1.1\r\nHost:site.com\r\nConnection:keep-alive\r\n\r\nGET / HTTP/1.1\r\nHost:site.com\r\nConnection:keep-alive\r\n\r\nGET / HTTP/1.1\r\nHost:site.com\r\nConnection:keep-alive\r\n\r\nGET / HTTP/1.1\r\nHost:site.com\r\nConnection:close\r\n\r\n";
    send(Connection, MTD, sizeof(MTD), NULL);
    char MOTD[1];
    int result;
    while ((result = recv(Connection, MOTD, 1, NULL)) > 0){
        std::cout << MOTD[0]; // ...
    }
    if (result == 0) {
        // end of stream
        std::cout << "end of stream";
        close(Connection);
    } else if (result < 0) {
        // error
        std::cout << "error";
        perror("recv"); // at least
        close(Connection);
    } else {
        std::cout << "data received";
        // data received, in MOTD[0..result-1]
    }
};

最佳答案

result=recv(Connection, MOTD, 1, NULL);
while(recv(Connection, MOTD, 1, NULL)){

这毫无意义。第一个 recv() 将至少一个字节读入缓冲区或将 result 设置为零或 -1,因此您立即忽略它所做的一切并发出另一个 recv (),您忽略其结果。它应该更像这样:

while ((result = recv(Connection, MOTD, 1, NULL)) > 0){
    // data received, in MOTD[0..result-1]
}
if (result == 0) {
    // end of stream
    close(Connection);
} else if (result < 0) {
    // error
    perror("recv"); // at least
    close(Connection);
}

注意您根本没有使用 HTTP keepalive。您正在为每个请求创建一个新套接字并且永远不会关闭它,至少在您使用此答案中的代码之前是这样。您通过Connection: keepalive header 告诉服务器保持该连接有效,这只会浪费服务器资源。要么正确使用 HTTP keep-alive,要么在每次请求后关闭套接字。

关于c++ - Bug 保活延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43062944/

相关文章:

C++ 未定义对已定义常量的引用

unit-testing - 远程主机在接收时强行关闭了连接

c - 在 C 中通过 TCP 发送和接收整数值

c# - 在从 python 服务器到 c# 客户端的 tcp 传输期间丢失数据

go - HTTP重用连接条件

java - 如何防止我的 UDP keepalive 使用 100% CPU?

c++ - 为什么函数指针定义可以使用任意数量的与号 '&' 或星号 '*' ?

c++ - Open GL 旋转

java - 如何在 docker 镜像中的 Spring Boot 应用程序中禁用保持 Activity 状态

c++ - 哪个 STL 容器最适合 std::sort? (这还重要吗?)