Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 臭虫存活延迟_C++_Sockets_Keep Alive - Fatal编程技术网

C++ 臭虫存活延迟

C++ 臭虫存活延迟,c++,sockets,keep-alive,C++,Sockets,Keep Alive,这段代码使用keep alive连接以加载许多共享相同IP地址的域,但在前25个域之后有一个bug,即每次加载域都会延迟30秒!如何解决这个问题 #pragma comment(lib,"ws2_32.lib") #include <WinSock2.h> #include <iostream> int main(){ WSAData wsaData; WORD DllVersion = MAKEWORD(2, 1); if (WSAStartup

这段代码使用keep alive连接以加载许多共享相同IP地址的域,但在前25个域之后有一个bug,即每次加载域都会延迟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]
    }
};
#pragma注释(lib,“ws2_32.lib”)
#包括
#包括
int main(){
WSAData WSAData;
单词DllVersion=MAKEWORD(2,1);
if(WSAStartup(DllVersion和wsaData)!=0){
MessageBoxA(NULL,“Winsock启动失败”,“错误”,MB|U OK | MB|U ICONERROR);
出口(1);
}
地址中的SOCKADDR_;
int sizeofadr=sizeof(addr);
addr.sin_addr.s_addr=inet_addr(“123.123.123.123”);
地址sin_端口=htons(80);
addr.sin_family=AF_INET;
套接字连接=套接字(AF\u INET,SOCK\u STREAM,NULL);
if(connect(Connection,(SOCKADDR*)和addr,sizeofadr)!=0)
{
MessageBoxA(NULL,“连接失败”,“错误”,MB_OK | MB_ICONERROR);
返回0;
}
标准::cout
这毫无意义。第一个
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);
}
while((结果=recv(连接,MOTD,1,NULL))>0){
//收到的数据,单位为MOTD[0..result-1]
}
如果(结果==0){
//断流
关闭(连接);
}否则如果(结果<0){
//错误
perror(“recv”);//至少
关闭(连接);
}
注意:您根本没有使用HTTP keepalive。您正在为每个请求创建一个新套接字,并且从不关闭它,至少在您使用此答案中的代码之前是这样。您还通过
连接:keepalive
头通知服务器保持该连接活动,这只会浪费服务器资源。或者使用HTTP keep alive pro每次请求后,请插入或关闭插座

这毫无意义。第一个
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);
}
while((结果=recv(连接,MOTD,1,NULL))>0){
//收到的数据,单位为MOTD[0..result-1]
}
如果(结果==0){
//断流
关闭(连接);
}否则如果(结果<0){
//错误
perror(“recv”);//至少
关闭(连接);
}


注意:您根本没有使用HTTP keepalive。您正在为每个请求创建一个新套接字,并且从不关闭它,至少在您使用此答案中的代码之前是这样。您还通过
连接:keepalive
头通知服务器保持该连接活动,这只会浪费服务器资源。或者使用HTTP keep alive pro每次请求后,请关闭或关闭套接字。

您的代码中有一个更大的错误:您有一个大小为零的数组,并要求
recv
向其中写入一个字节,从而使其溢出,并具有未定义的行为。在接收数据的循环中也可能有一个错误,即您没有检查失败。记住在<代码> Rev当连接被关闭时返回<代码> 0代码>代码,但是当出现错误时,代码< SokKyOrthEngult(通常是代码> -1 < /代码>)。在C++中,所有非零值都被认为是“真”的。,因此,即使出现不可恢复的故障,您仍然会像什么也没发生一样继续。让循环一次读取一个字节实际上是无效的。HTTP中的行终止符定义为
\r\n
,而不是
\n
@Someprogrammerdude:所有基于BSD/POSIX的套接字API实现,包括WinSock,在套接字上返回-1操作错误。Windows恰好有一个额外的
SOCKET\u ERROR
常量,该常量被定义为-1,用于代码可读性。代码中有一个更大的错误:您有一个大小为零的数组,并要求
recv
向其中写入一个字节,从而使其溢出并具有未定义的行为。可能存在重复的错误在您的循环中接收数据,即不检查失败。记住,当连接关闭时,代码< > ReV< <代码>返回<代码> 0代码>代码,但当出现错误时,代码> SokKyOrthsEngult(通常是代码> -1 < /C>)。C++中所有非零值都被认为是“真”的。,因此,即使出现不可恢复的故障,您仍然会像什么也没发生一样继续。让循环一次读取一个字节实际上是无效的。HTTP中的行终止符定义为
\r\n
,而不是
\n
@Someprogrammerdude:所有基于BSD/POSIX的套接字API实现,包括WinSock,在套接字上返回-1操作错误。Windows恰好有一个额外的
SOCKET\u ERROR
常量,它被定义为-1,用于代码可读性。EJP Done,recv返回是流结束,这意味着它结束时没有错误。在25个域之后,每个域加载的30秒延迟仍然是一个问题。SOCKET现在正在关闭,因为我正在使用此代码。我认为正在加载一个keep-alive套接字,我如何正确使用它?您不明白“正确使用HTTP keep-alive或在每次请求后关闭套接字”的哪一部分?要正确使用“HTTP keep-alive”,我的代码中应该做哪些更改?@JavaOdd太宽了。首先,重新使用连接,而不是关闭连接。请参阅RFC.EJP Done,recv返回是流结束,这意味着它不会出错。25个域后每个域加载的30秒延迟仍然是一个问题。套接字现在正在关闭,因为我使用了此代码。我以为我正在加载一个保持活动的套接字,怎么可能我是否正确使用它?您不明白“正确使用HTTP保持活动状态或在每次请求后关闭套接字”的哪一部分?我的代码中应该做哪些更改才能正确使用“HTTP保持活动状态”?@JavaOdd太宽了。首先,重新使用连接,而不是关闭连接。请参阅RFC。