Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML 2.0 Network] Lagi przy wysyłaniu pakietów

Ostatnio zmodyfikowano 2013-08-03 20:28
Autor Wiadomość
RazzorFlame
Temat założony przez niniejszego użytkownika
[SFML 2.0 Network] Lagi przy wysyłaniu pakietów
» 2013-08-02 17:43:47
Otóż powiem wam tak, od kilku godzin siedze nad prostą gierką w sfml ofc przez neta. Łączenie z serwer/client i na odwrót działa, sprawdzałem razem z Megatronem i wszystko ok, chociaż dzieli nas prawie cała Polska. No więc tak, kiedy postanowiłem dodać do clienta oprawkę graficzną (przyznam się bez bicia że dopiero wyświetlam postać w pozycji odebranej od serwera). Łącze się za pomocą protokołu TCP. I nie ogarniam tego. Jest tak, że kiedy wpisuje login i hasło, wszystko działa bardzo szybko przychodzi odp. od serwera (jeśli odnaleziono konto z takimi passami). Wszystko pięknie mi się wczytuje z pliku. Ale już kiedy po wykonaniu komendy od gracza (też pięknie dochodzi - pakiet oczywiście) wysyłam jego dane w taki sam sposób co przy logowaniu dostaje prawie to co bym chciał (tzn. to co wysłałem z serwera, sprawdzam czy jest poprawnie wykonana komenda, i jest). Żadnego błędu nie ma na cliencie i pięknie dochodzi. Ale wygląda na to że client "generuje" sobie sam i odpiera pakiety. Jest tak że kiedy wysyłam dane z klienta (o komendzie) to natychmiast przychodzą i sie wykonują. Na moje oko powinno dojść do clienta to co wysłałem. Dobra do rzeczy: poprawny pakiet danych z serwera jest w cliencie odbierany jakieś 10-25sek po wysłaniu (chociaż na cliencie cały czas dochodzi wiadomość). Czytałem wiele tematów (bardzo podobnych do mojego) na forum sfml-dev.org ale jakoś nie umiem sie w nich odnaleźć. Oto główne części kodu:


C/C++
void Server::sendPlayerInfo()
{
    if( m_Players.size() > 0 )
    {
        for( int i = 0; i < m_Players.size(); i++ )
        {
            sf::Packet pack;
            /*
            pack << std::string("STD")
            << m_Players[i]->getData()->getHealth()->m_HP
            << m_Players[i]->getData()->getHealth()->m_MaxHP
            << m_Players[i]->getData()->getEnergy()->m_EN
            << m_Players[i]->getData()->getEnergy()->m_MaxEN
            << m_Players[i]->getData()->getPosition()->X
            << m_Players[i]->getData()->getPosition()->Y;*/
            pack << std::string( "STD" ) << *( m_Players[ i ]->getData() );
            cout << m_Players[ i ]->getData()->getPosition()->X << "/" << m_Players[ i ]->getData()->getPosition()->Y << endl;
            if( m_Players[ i ]->getConnection()->sendPacket( pack ) == true )
            {
                cout << "Sent player info" << endl;
            }
            else
            {
                if( m_Players[ i ]->getConnection()->getLastFlag() == sf::Socket::Disconnected )
                {
                    cout << "Socket disconnected!" << endl;
                    m_Players.erase( m_Players.begin() + i );
                    i--;
                    continue;
                }
                else if( m_Players[ i ]->getConnection()->getLastFlag() == sf::Socket::Error )
                {
                    cout << "There's an error" << endl;
                }
                //if(m_Players[i]->getConnection()->getLastFlag() == sf::Socket::NotReady)
                //{
                // cout<<"Socket isn't ready!"<<endl;
                //}
                cout << "Failed to send data for: " <<*( m_Players[ i ]->getData()->getName() ) << endl;
            }
        }
    }
}

C/C++
bool Connection::isPacketReady( sf::Packet & pack )
{
    if( m_Socket.receive( pack ) != sf::Socket::Done )
    {
        return false;
    }
    else return true;
   
}
bool Connection::sendPacket( sf::Packet & pack )
{
    if( m_Socket.send( pack ) != sf::Socket::Done )
    {
        return false;
    }
    else return true;
   
}

C/C++
void Server::executeCommand()
{
    if( m_Players.size() > 0 )
    {
        for( int i = 0; i < m_Players.size(); i++ )
        {
            std::string pcmd = m_Players[ i ]->getCommand();
           
            if( pcmd == "moveUp" )
            {
                //cout<<"Parsing command"<<endl;
                m_Players[ i ]->getData()->getPosition()->Y--;
            }
            else if( pcmd == "moveDown" )
            {
                //cout<<"Parsing command"<<endl;
                m_Players[ i ]->getData()->getPosition()->Y++;
            }
            else if( pcmd == "moveLeft" )
            {
                //cout<<"Parsing command"<<endl;
                m_Players[ i ]->getData()->getPosition()->X--;
            }
            else if( pcmd == "moveRight" )
            {
                //cout<<"Parsing command"<<endl;
                m_Players[ i ]->getData()->getPosition()->X++;
            }
           
        }
    }
    sendPlayerInfo();
    if( m_WaitingConnection.size() > 0 )
    {
        for( int i = 0; i < m_WaitingConnection.size(); i++ )
        {
            std::string pcmd = m_WaitingConnection[ i ]->getCommand();
            if( pcmd.substr( 0, 5 ) == "login" )
            {
                int pos, len;
                pos = pcmd.find( ';' );
                len = pcmd.find_last_of( ';' );
                std::string login = pcmd.substr( pos + 1, len - pos - 1 );
                std::string password = pcmd.substr( len + 1 );
                cout << login << "/" << password << endl;
                for( int ip = 0; ip < m_PlayerDatabase.size(); ip++ )
                {
                    if( *( m_PlayerDatabase[ ip ].getLogin() ) == login
                    && *( m_PlayerDatabase[ ip ].getPassword() ) == password )
                    {
                        Player * pl = new Player( m_PlayerDatabase[ ip ] );
                        pl->setConnection( m_WaitingConnection[ i ] );
                        m_WaitingConnection.erase( m_WaitingConnection.begin() + i );
                        sf::Packet wstepneDane;
                        wstepneDane << std::string( "STD" ) << *( pl->getData() );
                        if( pl->getConnection()->sendPacket( wstepneDane ) == false )
                        {
                            cout << "First-After-Login data information for player called \"" <<*( pl->getData()->getName() ) << "\" failed" << endl;
                        }
                        m_Players.push_back( pl );
                        sendRedMessage( "Na serwer wszedl: " + *( pl->getData()->getName() ) );
                    }
                }
            }
        }
    }
   
}


EDIT: Ajć dałem tylko serwera. Tu macie najważniejsze kawałki kodu clienta:

C/C++
bool Player::sendCommand()
{
    sf::Packet pack;
    if( sf::Keyboard::isKeyPressed( sf::Keyboard::Left ) )
    {
        pack << std::string( "PCM" )
        << std::string( "moveLeft" );
    }
    else if( sf::Keyboard::isKeyPressed( sf::Keyboard::Up ) )
    {
        pack << std::string( "PCM" )
        << std::string( "moveUp" );
    }
    else if( sf::Keyboard::isKeyPressed( sf::Keyboard::Down ) )
    {
        pack << std::string( "PCM" )
        << std::string( "moveDown" );
    }
    else if( sf::Keyboard::isKeyPressed( sf::Keyboard::Right ) )
    {
        pack << std::string( "PCM" )
        << std::string( "moveRight" );
    }
    else
    {
        return false;
    }
    //cout<<"Sending command"<<endl;
    if( m_Connection->sendPacket( pack ) == false )
    {
        cout << "Nie mozna wyslac pakietu!" << endl;
        return false;
    }
    return true;
}

bool Player::parsePacket()
{
    sf::Packet pack;
    if( m_Connection->isPacketReady( pack ) == true )
    {
        if( m_Connection->getLastFlag() == sf::Socket::NotReady )
        {
            cout << "Dane nie przyszly!" << endl;
        }
        ///There's no problem with packet and there's received packet
        ///extract the first part of packet - packetType
        std::string packetType;
        pack >> packetType;
        if( packetType == "STD" )
        {
            ///Ok, we recognized the type, its FAL (First-After-Login) info.
            PlayerData data;
            if( pack >> data )
            {
                m_Data = data;
            }
            else cout << "Cannot read data from packet" << endl;
            ///We must copy extracted data to obiect member data (m_Data)
           
            cout << "\nYour position is: " << m_Data.getPosition()->X << "/" << m_Data.getPosition()->Y << endl;
           
            ///Let's put TEST info about player:
           
            /*cout<<"You logged as: "<<*(m_Data.getName())
            <<"\nYour rank is: "<<*(m_Data.getRank())
            <<"\nYour position is: "<<m_Data.getPosition()->X<<"/"<<m_Data.getPosition()->Y
            <<"\nYour health is: "<<m_Data.getHealth()->m_HP<<"/"<<m_Data.getHealth()->m_MaxHP
            <<"\nYour energy is: "<<m_Data.getEnergy()->m_EN<<"/"<<m_Data.getEnergy()->m_MaxEN;*/
            //cout<<"Odebralem pakiet danych!"<<endl;
        }
        else if( packetType == "WRN" )
        {
            std::string msg;
            pack >> msg;
            cout << msg << endl;
        }
        return true;
    }
    else if( m_Connection->getLastFlag() == sf::Socket::Disconnected )
    {
        ///Oh no! Server disconnected, we better put suitable text to output
        ///REMEMBER!!! Change COUT to graphic info.
        cout << "Fatal Error: Server closed the connection!" << endl;
        return false;
    }
    return false;
}

C/C++
void Client::mainClient()
{
    app.create( sf::VideoMode( 800, 600, 32 ), "War Alert", sf::Style::Close );
   
    Connection ccon;
   
    int port = 32281;
   
    sf::IpAddress addr;
    cout << "Give an address of server: ";
    cin >> addr;
    if( ccon.getSocket()->connect( addr, port ) != sf::Socket::Done )
    {
        cout << "There's an error! We cannot connect to address " << addr.toString() << endl;
        return;
    }
   
    Player pl;
    pl.setConnection( & ccon );
    pl.login();
   
    sf::Image img;
    img.loadFromFile( "data/graphics/player.png" );
    img.createMaskFromColor( sf::Color( 255, 0, 255 ) );
    sf::Texture tex;
    tex.loadFromImage( img );
    tex.setSmooth( false );
    sf::Sprite spr;
    spr.setTexture( tex );
    spr.setTextureRect( sf::IntRect( 0, 0, 40, 40 ) );
   
    while( app.isOpen() )
    {
        sf::Event ev;
        while( app.pollEvent( ev ) )
        {
            if( ev.type == sf::Event::Closed )
                 app.close();
           
        }
       
        if( pl.parsePacket() == true )
        {
            //cout<<"Odebralem dane"<<endl;
        }
        pl.sendCommand();
       
        app.clear( sf::Color::White );
       
        //cout<<spr.getPosition().x<<"/"<<spr.getPosition().y<<endl;
        spr.setPosition( pl.getData()->getPosition()->X * 40,
        pl.getData()->getPosition()->Y * 40 );
        app.draw( spr );
        app.display();
    }
   
}
P-89304
pekfos
» 2013-08-02 17:46:42
Popraw nazwę tematu.
P-89305
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2013-08-02 17:48:00
Poprawiłem, a z ciekawości pisze coś o tym w lekcji o zakładaniu tematów? :)

Edit: Widze że sie wam odechciało :/ Może sam coś znajde. Jeszcze nie zamykam ;D
P-89306
ison
» 2013-08-03 13:38:49
jak pchasz te pakiety co klatkę to się nie dziw, że nie nadążasz z ich odbieraniem
P-89386
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2013-08-03 18:09:00
Czyli jeśli ogranicze do powiedzmy 30 pakietów na sekunde na 1 clienta to będzie ok? Właśnie na sfml-dev.org na forum coś tak mówili.

Edit:
Działa! Działa! Działa! Ison jestem Ci bardzo wdzieczny :) Wszystko działa aż sie grać chce!
P-89398
MrPoxipol
» 2013-08-03 19:30:40
Kod może się jeszcze przydać, komuś kto będzie miał podobny problem...
P-89399
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2013-08-03 19:50:44
@UP z isonem omówiliśmy problem. BTW jak ty przywróciłeś mój kod? Nie widze żebyś był adminem ;d
P-89400
DejaVu
» 2013-08-03 20:27:23
Ja to zrobiłem z prostego powodu - skoro zakłada się temat i oczekuje się pomocy i ta została udzielona, to nie wypada później wycinać treści, która może w przyszłości się przydać innym.
P-89401
« 1 » 2
  Strona 1 z 2 Następna strona