簡體   English   中英

簡單的HTTP客戶端c recv()塊

[英]simple HTTP client c recv() blocks

我嘗試用c編寫簡單的HTTP客戶端,當我執行程序一段時間后,我有時從網站上獲取數據。 特定的recv()塊,並關閉連接。 解決這個問題的最佳方法是什么? 我仍然想獲取網站數據。

ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
if (iResult = getaddrinfo(s1, "http", &hints, &result)) {
    printf("getaddrinfo failed with error: %d\n", iResult);
    WSACleanup();
    return 1;
}
// Attempt to connect to an address until one succeeds

for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

    // Create a SOCKET for connecting to server
    ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
        ptr->ai_protocol);
    if (ConnectSocket == INVALID_SOCKET) {
        printf("socket failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }


    iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        closesocket(ConnectSocket);
        ConnectSocket = INVALID_SOCKET;
        continue;
    }
    break;
}

freeaddrinfo(result);

if (ConnectSocket == INVALID_SOCKET) {
    printf("Unable to connect to server!\n");
    WSACleanup();
    return 1;
}


// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
    printf("send failed with error: %d\n", WSAGetLastError());
    closesocket(ConnectSocket);
    WSACleanup();
    return 1;
}

// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
    printf("shutdown failed with error: %d\n", WSAGetLastError());
    closesocket(ConnectSocket);
    WSACleanup();
    return 1;
}

// Receive until the peer closes the connection

do {        
    iResult = recv(ConnectSocket, recvbuf, recvbuflen-1, 0);
    if ( iResult > 0 ) {
         flag = 1;
         recvbuf[iResult] = '\0';
         printf("%s\n",recvbuf);
    }
    else if ( iResult == 0 ) {
            if(!flag) { 
                printf("conection close before recv data\n");
            } else {
                printf("conection close\n");
                break;
            }
    }
    else {
        printf("recv failed with error: %d\n", WSAGetLastError());
    }
} while(iResult>1);


// cleanup
closesocket(ConnectSocket);
WSACleanup();

return 0;

}

我已經使用HTTP協議概念並將其發送到在此模板中嘗試過的每個URL:sendbuf =“ GET / [url path] HTTP 1.0 / r / nHost:[www.pure_url.com] / r / n / r / n“

編輯:我已經嘗試過[DaSourcerer建議],更改為HTTP / 1.1並添加了Connection:close,但仍有一段時間我有時沒有獲取數據。

我還補充道:

int tcp_timeout=10000;
unsigned int  sz = sizeof(tcp_timeout);
setsockopt(ConnectSocket, SOL_SOCKET, SO_RCVTIMEO,
(char*)&tcp_timeout, sz); 

這個想法沒有幫助。

我認為您的超時時間太嚴格。 您發送的標頭還將激發服務器等待進一步的輸入。 嘗試這個:

GET /path HTTP/1.1
Host: example.com
Connection: close

還需要提及的是Host是HTTP / 1.1中引入的標頭。 在HTTP / 1.0中沒有意義。 您可能還會對RFC 7230的3.3.3節感興趣因為您幾乎肯定會在HTTP / 1.1中遇到塊編碼的消息。 不過,請不要擔心:可以使用簡單的狀態機進行解析。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM