簡體   English   中英

C WINAPI recv()在收到所有數據之前返回0

[英]C WINAPI recv() returns 0 before all data is recieved

我正在使用MSDN的recv()頁面中的代碼,但我更改了要發送的數據以及目標端口和IP地址,以發送HTTP GET請求以獲取google.com/index.php。 每次運行它時,recv()在獲取大部分頁面(但不是全部)后都返回0。 我用wireshark驗證了整個頁面已被接收,但是它在<a href=//google.co之后停了下來,后跟一個非ASCII符號。

這是我正在使用的代碼,我刪除了大部分注釋和錯誤檢查,但與上面的鏈接相同:

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

int main() {
    WSADATA wsaData;
    int iResult;

    SOCKET ConnectSocket = INVALID_SOCKET;
    struct sockaddr_in clientService; 

    char *sendbuf = "GET /index.php\r\nHost: www.google.com\r\n\r\n";
    char recvbuf[512];
    int recvbuflen = 512;

    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr( "74.125.224.180" );
    clientService.sin_port = htons( 80 );

    iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );

    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );

    printf("Bytes Sent: %ld\n", iResult);

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

    // Receive until the peer closes the connection
    do {

        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 ){
            printf("%512s", recvbuf);
            //printf("recv returned %d... got %d bytes\n", iResult, recvbuflen);
        }
        else if ( iResult == 0 )
            printf("\n\nConnection closed\n");
        else
            printf("\n\nrecv failed: %d\n", WSAGetLastError());

    } while( iResult > 0 );

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

    return 0;
}

我正在使用mingw32 4.2.1版在Linux上進行編譯。

我只看了一眼,但是最明顯的錯誤是:

    if ( iResult > 0 ){
        printf("%512s", recvbuf);

沒有人會為您編寫使C字符串正常工作的NUL字符。 特別是,由於打印字符串意味着要搜索NUL字符,並且沒有任何通過網絡發送的字符,因此在recv之后的最后一個printf也可能會吐出前一次循環迭代中緩沖區中的一些垃圾。 您可以嘗試如下操作:

if (iResult > 0)
{
   char *p = recvbuf;
   while (iResult--)
      fputc(*p++, stdout);
}

這樣,您僅打印recv告訴您在緩沖區中的字符。

暫無
暫無

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

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