梁越

服务端和客户端心跳包机制

0 人看过

面试问的一个问题

客户端和服务端建立连接后,如果客户端断开连接了,服务端要怎么感知到断开呢

在我的服务器项目里,服务端和客户端之间会发送心跳包

例如在客户端的心跳包代码,每隔一秒发送一个心跳包,指令为60000

private void OnHeart()
{
    if (tcp == null) return;
    if (data.State < C_SOCKET_STATE.C_ConnectSecure) return;

    float ftime = Time.realtimeSinceStartup - data.time_Heart;
    if (ftime < ConfigXML.xml.HeartTime) return;

    data.time_Heart = Time.realtimeSinceStartup;
    begin(60000);
    sss((int)0);
    end();
}

服务端收到之后之后,更新对应连接的最后心跳时间,同时每个连接中还有checkConnect的检测超时线程,如果当前时间-最后心跳时间>心跳间隔,则感知到客户端断开连接了,服务端的代码如下

void net::EpollServer::checkConnect(S_CLIENT_BASE* c)
{
    int temp = 0;
    // if (c->closeState == func::S_CLOSE_SHUTDOWN)
    // {
    //     temp = (int)time(NULL) - c->time_Close;
    //     if (c->is_RecvCompleted && c->is_SendCompleted)
    //     {
    //         closeSocket(c->socketfd, c, 2001);
    //     }
    //     else if (temp > 3)
    //     {
    //         closeSocket(c->socketfd, c, 2002);
    //     }
    //     return;
    // }
    // temp = (int)time(NULL) - c->time_Connet;
    // if (c->state == func::S_Connect)
    // {
    //     if (temp > 10)
    //     {
    //         if (this->onTimeoutEvent != nullptr) this->onTimeoutEvent(this, c, 2002);
    //         shutDown(c->socketfd, 0, c, 2002);
    //         return;
    //     }
    // }

    temp = (int)time(NULL) - c->time_Heart;
    if (temp > func::__ServerInfo->HeartTime)
    {
        if (this->onTimeoutEvent != nullptr) this->onTimeoutEvent(this, c, 2003);
        shutDown(c->socketfd, 0, c, 2003);
        return;
    }
}

感知断开后直接shutdown