Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: network-management with SFML 2  (Read 3709 times)

0 Members and 1 Guest are viewing this topic.

Fred_FS

  • Newbie
  • *
  • Posts: 48
    • View Profile
network-management with SFML 2
« on: August 31, 2011, 01:12:42 pm »
Hello,

I am pretty new to networking and have just read a few tutorials about it and read the SFML documentation and treid to programm a little network-manager.
It's nothing special. One user should be able to be the host and an other one should be allowed to join the "game".

I didn't want to use a seperate server-application, so the user can choose if he wants to host a game and "be" the server.
Therefore I have a network-manager class. It does all the server-stuff(selector and listener). This network-manager is run in a sperate thread, if the user hosts a game and the methode looks like this:
Code: [Select]

while( true )
{
if( selector_.Wait() )
{
if( selector_.IsReady( listener_ ) )
{
// listener is ready, so there is a pending connection
sf::TcpSocket* client = new sf::TcpSocket;
if( listener_.Accept( *client ) == sf::Socket::Done )
{
clients_.push_back( client );
selector_.Add( *client );
client->SetBlocking( false );
std::cout << "GAME_INFO: Client connected with IP " << client->GetRemoteAddress() << std::endl;

}
}
else
{
// Check whether the other objects are ready
for( std::list<sf::TcpSocket*>::iterator it = clients_.begin();
it != clients_.end(); ++it )
{
sf::TcpSocket client = **it;
if( selector_.IsReady( client ) )
{
sf::Packet packet;
sf::Socket::Status state = client.Receive( packet );
if( state == sf::Socket::Done )
{
handle_message( client, packet );
}
}
}
}
}
}

Basiclly it's taken from the documentation. But now I have a problem. A use may disconnect for any reason. In this case I am not able to remove the socket.
What I tried:
Code: [Select]

for( std::list<sf::TcpSocket*>::iterator it = clients_.begin();
it != clients_.end();)
{
sf::TcpSocket client = **it;
if( selector_.IsReady( client ) )
{
sf::Packet packet;
sf::Socket::Status state = client.Receive( packet );
if( state == sf::Socket::Done )
{
handle_message( client, packet );
++it;
continue;
}
else if( state == sf::Socket::Disconnected )
{
selector_.Remove( client );
std::cout << "Client disconnected with IP " << client.GetRemoteAddress();
it = clients_.erase( it );
}
}
}


But this is not working. If i put "++it" to the end of the loop, my socket won't receive any messages. Even if the socket is not removed, it will not catch the welcome-message which I send to the clients.

Has anyone already programmed a network-manager with SFML 2 and can give me some hint? Or would you do it in a completly other way?

Thanks for your help,
Fred

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
network-management with SFML 2
« Reply #1 on: August 31, 2011, 01:23:08 pm »
Quote
If i put "++it" to the end of the loop, my socket won't receive any messages

I think you just need to put it in a "else" block, so that it is only executed if the socket was not ready -- and won't conflict with "++it" or "it = erase(it)".

Quote
Has anyone already programmed a network-manager with SFML 2 and can give me some hint? Or would you do it in a completly other way?

There are several ways of implementing a network client/server architecture, but this one is ok for what you do.
I think your problem is simply to properly remove an element in the middle of an iteration, it has nothing to do with networking.
Laurent Gomila - SFML developer

Fred_FS

  • Newbie
  • *
  • Posts: 48
    • View Profile
network-management with SFML 2
« Reply #2 on: September 03, 2011, 11:42:34 am »
What a stupid mistake, thank you :).

Currently I am thinking about a lobby system. Is there any way to search for all servers? Games can be hosted by several people with different ips. My plan was to connect to every server and get a "game-information" message wich is diplayed. But how to find out which ips are hosting a game? I don't think that it is very clever, if I just step through all 255 possible ips and try to connect. Is there an easier way?

thePyro_13

  • Full Member
  • ***
  • Posts: 156
    • View Profile
network-management with SFML 2
« Reply #3 on: September 03, 2011, 12:25:00 pm »
Local servers(LAN) usually use broadcast, client can just listen on the server port. Servers broadcast themselves every other interval. Or you can do the reverse and have the client broadcast a "looking for servers" message, and servers respond with their IP/port.

Over the internet, you'd need to look into master servers, but since you say their are only 255 possible IPs, I suspect you're doing LAN.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
network-management with SFML 2
« Reply #4 on: September 03, 2011, 12:27:55 pm »
To find all game servers on a local network, you can use UDP broadcast. Each server broadcasts (sends to everyone) a special message on a specific UDP port, and games searching for servers listen to this UDP port and process the received messages.
Laurent Gomila - SFML developer