2017-03-28 12 views
0

このコードはキープアライブを使用して同じ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] 
    } 
}; 
+4

あなたのコードには大きなバグがあります:サイズが0の配列を持ち、 'recv'に1バイトを書き込んでオーバーフローさせ、*未定義の振る舞い*を持たせてください。 –

+1

[同じIPのドメインを多数クロール]の可能な複製(http://stackoverflow.com/questions/43061474/crawl-lots-of-domains-from-the-same-ip) –

+2

バグがありますあなたのループは、データを受信する、つまり、あなたは失敗を確認しません。 'recv'は接続が閉じているときは' 0'を返し、エラーがあるときは 'SOCKET_ERROR'(通常は' -1')を返します。 C++では、ゼロ以外の値はすべて「true」と見なされるため、回復不能な障害が発生しても、何も起こらないかのように処理を続けます。そして、一度に1バイトを読むループを持つことは実際には効果がありません。 –

答えて

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

これは全く意味がありません。最初のrecv()は少なくとも1バイトをバッファに読み込むか、resultを0または-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); 
} 

NBあなたはHTTPキープアライブをまったく使用していません。この答えでコードを使用するまでは、リクエストごとに新しいソケットを作成し、決して閉じません。 は、サーバーのリソースを浪費するだけの接続を維持するために、Connection: keepaliveヘッダーを介してサーバーに伝えています。 HTTPキープアライブを正しく使用するか、各要求の後にソケットを閉じます。

+0

EJP完了、recv returnはストリームの終わりです。つまり、エラーなしで終了します。 25ドメイン後の各ドメイン負荷の30秒間の遅延はまだ問題です。 – JavaOdd

+0

@JavaOdd編集を参照してください。 – EJP

+0

このコードを使用しているので、ソケットが閉じられています。 1つのキープアライブソケットをロードしていたと思いますが、どうすれば正しく使用できますか? – JavaOdd