Ejemplo n.º 1
0
void NetworkApp::ReceiverMainLoopIteration()
{
	server->Process();

	NetworkServer::ConnectionMap connections = server->GetConnections();
	Ptr(MessageConnection) clientConnection = (connections.size() > 0) ? server->GetConnections().begin()->second : Ptr(MessageConnection)();
	if (!clientConnection)
	{
		QApplication::exit();
		return;
	}

	if (clientConnection->IsReadOpen())
	{
		if (statsPrintTimer.Test())
		{
			const tick_t sendFinishTick = Clock::Tick();
			double timespan = (float)Clock::TimespanToSecondsD(transferStartTick, sendFinishTick);
			LOG(LogUser, "Have received %d fragments (+%d out-of-order) (%.2f%%). Elapsed: %.2f seconds. Bytes received: %d. Transfer rate: %s/sec.", 
				nextFragment, fragments.size(), (nextFragment + fragments.size()) * 100.f / totalFragments,
				(float)timespan, bytesReceived, FormatBytes((bytesReceived/timespan)).c_str());
			clientConnection->DumpStatus();
			statsPrintTimer.StartMSecs((float)printIntervalMSecs);
		}
		QTimer::singleShot(10, this, SLOT(ReceiverMainLoopIteration()));
	}
	else
	{
		if (nextFragment == totalFragments)
		{
			LOG(LogUser, "Finished receiving all fragments. File '%s' saved to disk, size: %d bytes. Closing connection.",
				filename.c_str(), bytesReceived);
		}
		else
		{
			clientConnection->DumpStatus();
			LOG(LogUser, "Error: Sender specified the file '%s' to contain %d fragments, but the connection was closed after "
				"receiving %d fragments. Received a partial file of %d bytes.", filename.c_str(), totalFragments, nextFragment, bytesReceived);
		}
		clientConnection->Close(15000);

		QApplication::quit();
	}
}
Ejemplo n.º 2
0
void KristalliProtocolModule::Update(f64 frametime)
{
    // Update method for multiconnection.
    if (!serverConnection_map_.isEmpty())
        connectionArrayUpdate();


    // Pulls all new inbound network messages and calls the message handler we've registered
    // for each of them.
    if (serverConnection)
        serverConnection->Process();


    // Note: Calling the above serverConnection->Process() may set serverConnection to null if the connection gets disconnected.
    // Therefore, in the code below, we cannot assume serverConnection is non-null, and must check it again.

    // Our client->server connection is never kept half-open.
    // That is, at the moment the server write-closes the connection, we also write-close the connection.
    // Check here if the server has write-closed, and also write-close our end if so.
    if (serverConnection && !serverConnection->IsReadOpen() && serverConnection->IsWriteOpen())
        serverConnection->Disconnect(0);


    // Process server incoming connections & messages if server up
    if (server)
    {
        server->Process();

        // In Tundra, we *never* keep half-open server->client connections alive.
        // (the usual case would be to wait for a file transfer to complete, but Tundra messaging mechanism doesn't use that).
        // So, bidirectionally close all half-open connections.
        NetworkServer::ConnectionMap connections = server->GetConnections();
        for(NetworkServer::ConnectionMap::iterator iter = connections.begin(); iter != connections.end(); ++iter)
            if (!iter->second->IsReadOpen() && iter->second->IsWriteOpen())
                iter->second->Disconnect(0);
    }

    if ((!serverConnection || serverConnection->GetConnectionState() == ConnectionClosed ||
            serverConnection->GetConnectionState() == ConnectionPending) && serverIp.length() != 0)
    {
        const int cReconnectTimeout = 5 * 1000.f;
        if (reconnectTimer.Test())
        {
            if (reconnectAttempts)
            {
                PerformConnection();
                --reconnectAttempts;
            }
            else
            {
                LogInfo("Failed to connect to " + serverIp + ":" + ToString(serverPort));
                // If connection fails we just ignore it. Client has no use for information if initial connection failed.
                //framework_->GetEventManager()->SendEvent(networkEventCategory, Events::CONNECTION_FAILED, 0);
                reconnectTimer.Stop();
                serverIp = "";
            }
        }
        else if (!reconnectTimer.Enabled())
            reconnectTimer.StartMSecs(cReconnectTimeout);
    }

    // If connection was made, enable a larger number of reconnection attempts in case it gets lost
    if (serverConnection && serverConnection->GetConnectionState() == ConnectionOK)
    {
        // save succesfully established connection to messageconnection array with all connection properties.
        for (unsigned short connection = 0;; connection++)
        {
            if (!serverConnection_map_.contains(connection))
            {
                // Associative QMap stores all items sorted by Key. If array has one item terminated,
                // we fill it with next succesfull connection. Same is done in client.
                serverConnection_map_.insert(connection, serverConnection);
                serverIp_list_.insert(connection,serverIp);
                serverPort_list_.insert(connection,serverPort);
                serverTransport_list_.insert(connection, serverTransport);
                reconnectAttempts_list_.insert(connection, cReconnectAttempts);
                reconnectTimer.Reset();
                reconnectTimer_list_.insert(connection,reconnectTimer);

                serverConnection = 0;
                serverIp = "";
                serverPort = 0;

                break;
            }
        }
    }


    RESETPROFILER;
}
Ejemplo n.º 3
0
void KristalliProtocolModule::Update(f64 /*frametime*/)
{
    // Pulls all new inbound network messages and calls the message handler we've registered
    // for each of them.
    if (serverConnection)
    {
        PROFILE(KristalliProtocolModule_kNet_client_Process);
        serverConnection->Process();
    }

    // Note: Calling the above serverConnection->Process() may set serverConnection to null if the connection gets disconnected.
    // Therefore, in the code below, we cannot assume serverConnection is non-null, and must check it again.

    // Our client->server connection is never kept half-open.
    // That is, at the moment the server write-closes the connection, we also write-close the connection.
    // Check here if the server has write-closed, and also write-close our end if so.
    if (serverConnection && !serverConnection->IsReadOpen() && serverConnection->IsWriteOpen())
        serverConnection->Disconnect(0);
    
    // Process server incoming connections & messages if server up
    if (server)
    {
        PROFILE(KristalliProtocolModule_kNet_server_Process);

        server->Process();

        // In Tundra, we *never* keep half-open server->client connections alive. 
        // (the usual case would be to wait for a file transfer to complete, but Tundra messaging mechanism doesn't use that).
        // So, bidirectionally close all half-open connections.
        NetworkServer::ConnectionMap connections = server->GetConnections();
        for(NetworkServer::ConnectionMap::iterator iter = connections.begin(); iter != connections.end(); ++iter)
            if (!iter->second->IsReadOpen() && iter->second->IsWriteOpen())
                iter->second->Disconnect(0);
    }
    
    if ((!serverConnection || serverConnection->GetConnectionState() == ConnectionClosed ||
        serverConnection->GetConnectionState() == ConnectionPending) && serverIp.length() != 0)
    {
        const int cReconnectTimeout = 5 * 1000.f;
        if (reconnectTimer.Test())
        {
            if (reconnectAttempts)
            {
                PerformConnection();
                --reconnectAttempts;
            }
            else
            {
                ::LogInfo(QString("Failed to connect to %1:%2").arg(serverIp.c_str()).arg(serverPort));
                emit ConnectionAttemptFailed();

                reconnectTimer.Stop();
                serverIp = "";
            }
        }
        else if (!reconnectTimer.Enabled())
            reconnectTimer.StartMSecs(cReconnectTimeout);
    }

    // If connection was made, enable a larger number of reconnection attempts in case it gets lost
    if (serverConnection && serverConnection->GetConnectionState() == ConnectionOK)
        reconnectAttempts = cReconnectAttempts;
}