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

Author Topic: [SFML 2]List of all open games  (Read 4209 times)

0 Members and 1 Guest are viewing this topic.

Fred_FS

  • Newbie
  • *
  • Posts: 48
    • View Profile
[SFML 2]List of all open games
« on: January 06, 2013, 02:47:33 pm »
Hello,

currently I am working on a little network-game using SFML-network and I have a problem listing the open games.

In my current approach the server creates an own udp-thread in which it is waiting for broadcasting messages. The clients send such broadcasting messages to receive an answer from any server which is waiting for messages. This works for one server. But I want to list all open games, hence all servers which are waiting for clients. So I thought, that I need a while-loop to handle all the packets comming from the different servers.

But therefore I would have to use non-blocking udp-sockets, because a blocking one would end up waiting for packtes to receive, but none is comming in. So my code looks like:
sf::UdpSocket udp_socket;
sf::Packet pack;

if( udp_socket.send( pack, sf::IpAddress("255.255.255.255"), 12346) != sf::Socket::Done )
        return;

udp_socket.setBlocking( false );

sf::IpAddress sender;
unsigned short sender_port;    
while(udp_socket.receive(pack, sender, sender_port) == sf::Socket::Done )
{
        std::cout << "received" << std::endl;
}
 

With this code I never receive any packets, because the status of the receive-method is always 1(sf::Socket::NotReady). If I use the blocking udp_socket, I receive one packet from my existing server, but after that the next receive-command is blocking again and it is not going on.

Do you have any idea, what would be a possible solution to list all servers with a udp-broadcast?
My idea would be that the server sends a second packet after the first packet(after a short time of waiting) and if the client receives this "poisoned" packet, it will leave the loop. But I wonder, if there is a better solution.

Thanks for your help,
Fred

EDIT: Sorry I forgot to mention, that I am using SFML 2, which I downloaded a few days ago from git repository.
« Last Edit: January 06, 2013, 05:19:04 pm by Fred_FS »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SFML 2]List of all open games
« Reply #1 on: January 06, 2013, 07:13:50 pm »
If I understand correctly, the problem is not your code, it's that you never receive more than one message from your servers. Right?

If you receive all the messages, even blocking sockets should be ok -- as long as the corresponding thread doesn't do anything else.
Laurent Gomila - SFML developer

Fred_FS

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: [SFML 2]List of all open games
« Reply #2 on: January 07, 2013, 12:52:01 am »
No it is not exactly my problem. It's right, that I never receive more than one message from my servers, but I don't want to receive more messages.

My client sends one message to the server, the server answers and the client connects a TCP socket to the TCP-Server. This is the way it is supposed to work. So the udp broadcast is only necessary to contact the server and to find out how many servers exist.

Here is the code, my server handles udp messages.
The server is started in one seperate thread, which handles all TCP connections. This thread starts a new internal thread, which is listenting with an UDP socket.
The code of the UDP thread:
// Create a socket to receive a message from anyone
        sf::UdpSocket socket;

        // Listen to messages on the specified port
        if (socket.bind(port_ + 1) != sf::Socket::Done)
                return;
        std::cout << "Server is listening to port " << port_ + 1 << ", waiting for a message... " << std::endl;
        while( !quit_ )
        {
                // Wait for a message
                sf::Packet packet;
                sf::IpAddress sender;
                unsigned short senderPort;
                if (socket.receive(packet, sender, senderPort) != sf::Socket::Done)
                        return;

                std::cout << "Message received from client " << sender << std::endl;

                sf::Packet outPack;
                outPack << sf::IpAddress::getLocalAddress().toString();
                socket.send( outPack, sender, senderPort );
        }

        socket.unbind();
 

I see your point, that there must be messages, which are not received by my client, but in my opinion there are no more messages from the server. Or do I mess something up?
I also tried to create and bind the socket in the while loop and unbind it at the end of the loop, so that one socket is only waiting for one connection and sends one message and is unbind after that, but it didn't help.

Fred_FS

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: [SFML 2]List of all open games
« Reply #3 on: January 08, 2013, 07:22:23 pm »
I found a solution to my problem which is not exactly what I wanted, but the best I could get.

If anyone is interested in what I have done:

My server starts this UDP thread as in my last post.
If a client is looking for games, it will create an udp socket and send a broadcast message to all servers:
if( udp_socket_ )
        delete udp_socket_;

udp_time_ = 0.0f;

udp_socket_ = new sf::UdpSocket();
sf::Packet pack;

if( udp_socket_->send( pack, sf::IpAddress("255.255.255.255"), 12346) != sf::Socket::Done )
        return;

udp_socket_->setBlocking( false );
 

In the update-method of this game state my client is now waiting for answers from the servers, and if there is one, it will put it into a server list. This "waiting-procedure" will go on for about 10 seconds.
if( udp_socket_ )
{

        sf::IpAddress sender;
        unsigned short sender_port;    
        sf::Packet pack;

        if( (udp_socket_->receive(pack, sender, sender_port)) == sf::Socket::Done )
                games_list->addItem(sender.toString(), sender);

        udp_time_ += game_env_.render_time;

        if( udp_time_ >= 10.0 )
        {
                udp_time_ = 0.0f;
                delete udp_socket_;
                udp_socket_ = 0;
        }
}
 

By now I've tested this method only with one server. But this server is found without crashing and so I am confident, that it will also work with more than one server ;).