当客户端按Ctrl + c关闭时,服务器会连续处理上一个输入。为什么?

时间:2016-10-05 15:17:24

标签: c sockets

我在C中有一个客户端服务器程序。客户端在服务器收到命令时发送命令。

但是如果通过按 Ctrl + C 关闭客户端,服务器应用程序将处理先前的输入。

实施例

CLient.c                                Server.c
-------------------------------------------------
Enter COmmand: adf                     Command from client: adf

Enter COmmand: bbb                     Command from client: bbb

Enter Command: Ctrl+c                  Command from client: bb

我不明白为什么它处理以前的输入。

以下是我的主要逻辑。

main(){

    // bind, listen, accept is done.

            while(!done && !shutFlag){      //  Main server command Loop
        done = ReceiveRequestMessage(&request, connectedSock );
        if(done)
        {
            printf("Client closed the connection while recv() \n");
            printf("Listening for new client connection to establish... \n");
            connectedSock = accept(srvSock, (struct sockaddr *)&connectSAddr, &addrLen );
            printf("GetLastError: %d\n", GetLastError());
            done = FALSE;
            continue;

        }

        request.record[strlen(request.record)] ='\0';
        commandLen = strcspn(request.record, "\n\t");
        memcpy(sysCommand, request.record, commandLen);
        sysCommand[commandLen] = '\0';

        printf("Request recieved from client: %s -> Hex: %X\n\n", request.record, *(request.record));
    }

}

ReceiveRequestMessage功能:

static BOOL ReceiveRequestMessage(REQUEST *pRequest, SOCKET sd){
    LONG32 nRemainRecv = 0, nRecv;
    LPBYTE pBuffer;
    BOOL disconnect = FALSE;

    nRemainRecv = RQ_HEADER_LEN;
    pBuffer = (LPBYTE) pRequest;
    while(nRemainRecv > 0 &&  !disconnect )
    {
        nRecv = recv (sd, pBuffer, nRemainRecv, 0); // Reading the 1st 4 bytes(length of record)to pRequest.
        if ( nRecv > 0 )
            printf("Bytes received in request.rqLen: %d\n", nRecv);
        else if ( nRecv == SOCKET_ERROR ){
            printf("Connection closed\n");
            return TRUE;
        }

        disconnect = (nRecv == 0);      // check connection is closed 
        nRemainRecv -= nRecv;
        pBuffer += nRecv;       
    }

    /*  Read the request record */
    nRemainRecv = pRequest->rqLen;
    /* Exclude buffer overflow */
    nRemainRecv = min(nRemainRecv, MAX_RQRS_LEN);

    pBuffer = (LPSTR)pRequest->record;  
    while(nRemainRecv > 0 && !disconnect)
    {
        nRecv = recv(sd, pBuffer, nRemainRecv, 0);
        if(nRecv > 0)
            printf("Bytes Received in request.record: %d\n", nRecv);
        else if(nRecv == SOCKET_ERROR){
            printf("Connection closed");
            return TRUE;
        }

        disconnect = (nRecv == 0);          // check connection is closed 
        nRemainRecv -= nRecv;
        pBuffer += nRecv;       
    }

    return disconnect;
}

如何在客户端中单击 Ctrl + C 后消除上一个打印语句?

意思是:

每当客户端通过单击 Ctrl + C 或以任何方式断开连接。我该如何通知服务器?

1 个答案:

答案 0 :(得分:1)

  • 函数ReceiveRequestMessage()返回其变量disconnect的值。
  • 仅当recv()返回0时,该变量才会设置为非零。
  • recv()的文档承诺返回值0仅适用于远程端执行有序关闭(并且没有更多数据可用于接收)的情况。如果发生错误,它肯定会返回-1,而不是0
  • 假设客户端每次有效断开连接时都会执行有序关闭是不安全的,特别是假设它在被信号杀死时执行一次是不安全的,就像你在发送一个Ctrl + c。
  • 如果ReceiveRequestMessage()返回0而未修改其pRequest参数指向的对象,则调用者将看到先前发送的请求已重复。这就是你所观察到的。