示例#1
0
void irc::pingcheckfunc()
{
	if (pinged)
	{
		pinged = false;
	}
	else
	{
		qDebug() << "reconnection needed";
		name = name + "_";
		discon();
		con();
	}
}
示例#2
0
// This function is called from the network thread, no acces to server
// internal data should be made
void NetManager::CheckLinkDead()
{
    csTicks currenttime = csGetTicks();

    csArray<uint32_t> checkedClients;
    Client *pClient = NULL;

    // Delete all clients marked for deletion already
    clients.SweepDelete();

    while(true)
    {
        pClient = NULL;

        // Put the iterator in a limited scope so we don't hold on to the lock which may cause deadlock
        {
            ClientIterator i(clients);

            while(i.HasNext())
            {
                Client *candidate = i.Next();

                // Skip if already seen
                if(checkedClients.FindSortedKey(csArrayCmp<uint32_t, uint32_t> (candidate->GetClientNum())) != csArrayItemNotFound)
                    continue;

                checkedClients.InsertSorted(candidate->GetClientNum());
                pClient = candidate;
                break;
            }
        }

        // No more clients to check so break
        if(!pClient)
            break;

        // Shortcut here so zombies may immediately disconnect
        if(pClient->IsZombie() && pClient->ZombieAllowDisconnect())
        {
            /* This simulates receipt of this message from the client
             ** without any network access, so that disconnection logic
             ** is all in one place.
             */
            psDisconnectMessage discon(pClient->GetClientNum(), 0, "You should not see this.");
            if (discon.valid)
            {
                Connection* connection = pClient->GetConnection();
                HandleCompletedMessage(discon.msg, connection, NULL,NULL);
            }
            else
            {
                Bug2("Failed to create valid psDisconnectMessage for client id %u.\n", pClient->GetClientNum());
            }
        }
        else if (pClient->GetConnection()->lastRecvPacketTime+timeout < currenttime)
        {
            if (pClient->GetConnection()->heartbeat < 10 && pClient->GetConnection()->lastRecvPacketTime+timeout * 10 > currenttime)
            {
                psHeartBeatMsg ping(pClient->GetClientNum());
                Broadcast(ping.msg, NetBase::BC_FINALPACKET);
                pClient->GetConnection()->heartbeat++;
            }
            else
            {
                if(!pClient->AllowDisconnect())
                    continue;

                char ipaddr[20];
                pClient->GetIPAddress(ipaddr);

                csString status;
                status.Format("%s, %u, Client (%s) went linkdead.", ipaddr, pClient->GetClientNum(), pClient->GetName());
                psserver->GetLogCSV()->Write(CSV_AUTHENT, status);

                /* This simulates receipt of this message from the client
                 ** without any network access, so that disconnection logic
                 ** is all in one place.
                 */
                psDisconnectMessage discon(pClient->GetClientNum(), 0, "You are linkdead.");
                if (discon.valid)
                {
                    Connection* connection = pClient->GetConnection();
                    HandleCompletedMessage(discon.msg, connection, NULL,NULL);
                }
                else
                {
                    Bug2("Failed to create valid psDisconnectMessage for client id %u.\n", pClient->GetClientNum());
                }
            }
        }
    }
}