从服务器关闭客户端套接字打印出我已经打印的多个字符串

Closing a client socket from server print out multiple string that I already printed

我创建了一个接收 http 请求并打印该请求的服务器。我可以在不关闭客户端套接字的情况下成功打印出收到的 http 请求,但是当我关闭客户端套接字时,服务器会打印出我之前已经打印出的多个 http 请求。 这是我的代码:

int handleConnection(int sockfd)
{
    // sockfd is new_sockfd

    char fullReq[MAX_HEADER_SIZE];

    receiveReq(sockfd, fullReq);

    printf("fullReq in handleConnection\n%s", fullReq);
    close(sockfd); // bug occur when I close it
    return 0;
}

这是recvReq函数的代码:

int receiveReq(int sockfd, char *fullReq)
{

    char buffer[1];
    memset(buffer, 0, sizeof(buffer));
    char *bufferPtr = buffer;

    char terminators[] = {'\r', '\n'};

    int number_of_requests = 0;
    int matchedTerminators = 0;
    
    while(number_of_requests <= MAX_HEADER_SIZE)
    {
        if(matchedTerminators >= 4)
            break;

        recv(sockfd, bufferPtr, 1, 0);
        strncat(fullReq, bufferPtr, 1);
        number_of_requests++;

        if(buffer[0] == terminators[0] || buffer[0] == terminators[1])
            matchedTerminators++;
        else
            matchedTerminators = 0;
    }

    return 0;
}

如果我没有关闭套接字,输出:

fullReq in handleConnection
GET / HTTP/1.1

关闭套接字时的输出:

fullReq in handleConnection
GET / HTTP/1.1

fullReq in handleConnection
GET / HTTP/1.1

fullReq in handleConnection
GET / HTTP/1.1

more...

您应该检查 recv 的 return 代码。当客户端套接字关闭时,recv 很可能会失败(取决于您如何打开服务器的套接字),并且 bufferPtr 将保持相同的内容,即上次请求。您可以检测 recv 是否失败,例如因为客户端套接字已关闭,通过检查它是否有 returned -1。您可以查看有关 recv 的手册页,原因有多种 recv 可能会失败。