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: 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() ); 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; } cout << "Failed to send data for: " <<*( m_Players[ i ]->getData()->getName() ) << endl; } } } }
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; }
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" ) { m_Players[ i ]->getData()->getPosition()->Y--; } else if( pcmd == "moveDown" ) { m_Players[ i ]->getData()->getPosition()->Y++; } else if( pcmd == "moveLeft" ) { m_Players[ i ]->getData()->getPosition()->X--; } else if( pcmd == "moveRight" ) { 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: 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; } 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; } std::string packetType; pack >> packetType; if( packetType == "STD" ) { PlayerData data; if( pack >> data ) { m_Data = data; } else cout << "Cannot read data from packet" << endl; cout << "\nYour position is: " << m_Data.getPosition()->X << "/" << m_Data.getPosition()->Y << endl; } else if( packetType == "WRN" ) { std::string msg; pack >> msg; cout << msg << endl; } return true; } else if( m_Connection->getLastFlag() == sf::Socket::Disconnected ) { cout << "Fatal Error: Server closed the connection!" << endl; return false; } return false; }
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 ) { } pl.sendCommand(); app.clear( sf::Color::White ); spr.setPosition( pl.getData()->getPosition()->X * 40, pl.getData()->getPosition()->Y * 40 ); app.draw( spr ); app.display(); } }
|
|
pekfos |
» 2013-08-02 17:46:42 Popraw nazwę tematu. |
|
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 |
|
ison |
» 2013-08-03 13:38:49 jak pchasz te pakiety co klatkę to się nie dziw, że nie nadążasz z ich odbieraniem |
|
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! |
|
MrPoxipol |
» 2013-08-03 19:30:40 Kod może się jeszcze przydać, komuś kto będzie miał podobny problem... |
|
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 |
|
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. |
|
« 1 » 2 |