SFML TCP packet receive

ぐ巨炮叔叔 提交于 2019-12-12 01:35:00

问题


I send a packet as client to server and I want to the server sends that packet forward to all client, here is the code:

#include <iostream>
#include <SFML/Network.hpp>
using namespace std;
int main()
{
int fromID; // receive data from 'fromID'
int Message; // fromID's message

sf::SocketTCP Listener;
if (!Listener.Listen(4567))
    return 1;
// Create a selector for handling several sockets (the listener + the socket associated to each client)
sf::SelectorTCP Selector;

Selector.Add(Listener);

while (true)
{
    unsigned int NbSockets = Selector.Wait();
    for (unsigned int i = 0; i < NbSockets; ++i)
    {
        // Get the current socket
        sf::SocketTCP Socket = Selector.GetSocketReady(i);

        if (Socket == Listener)
        {
        // If the listening socket is ready, it means that we can accept a new connection
            sf::IPAddress Address;
            sf::SocketTCP Client;
            Listener.Accept(Client, &Address);
            cout << "Client connected ! (" << Address << ")" << endl;

            // Add it to the selector
            Selector.Add(Client);
        }
        else
        {
            // Else, it is a client socket so we can read the data he sent
            sf::Packet Packet;
            if (Socket.Receive(Packet) == sf::Socket::Done)
            {

               // Extract the message and display it
                Packet >> Message;
                Packet >> fromID;
                cout << Message << " From: " << fromID << endl;

                //send the message to all clients
                for(unsigned int j = 0; j < NbSockets; ++j)
                {
                    sf::SocketTCP Socket2 = Selector.GetSocketReady(j);

                    sf::Packet SendPacket;
                    SendPacket << Message;
                    if(Socket2.Send(SendPacket) != sf::Socket::Done)
                        cout << "Error sending message to all clients" << endl;
                }
            }
            else
            {
              // Error : we'd better remove the socket from the selector
                Selector.Remove(Socket);
            }
        }
    }
}
return 0;

}

Client code: in Player class I have this function :

void Player::ReceiveData()
{
 int mess;
 sf::Packet Packet;
 if(Client.Receive(Packet) == sf::Socket::Done)
 {
    Client.Receive(Packet);
    Packet >> mess;
    cout << mess << endl;
 }
}

main.cpp:

Player player;
player.Initialize();
player.LoadContent();
player.Connect();
..
..
//GAME LOOP
while(running==true)
{
   sf::Event Event;
   while(..) // EVENT LOOP
   {
   ...
   }
   player.Update(Window);
   player.ReceiveData();
   player.Draw(Window);
}

When I run this client code, the program not responding, freezes. The problem is with that ReceiveDate() function.


回答1:


All sockets, even the one created by SFML, are by default blocking. This means that when you try to receive when there is nothing to receive, the call will block, making your application seem "freezed".

You can toggle the blocking status of a SFML socket with the sf::SocketTCP::SetBlocking function.


The problem with sending to all clients failing is because you use GetSocketReady to get the clients to send to. That function only returns a socket for clients that are ready (i.e. the previous call to Wait marked the socket as having input).

You need to refactor the server to keep track of the connected clients in another way. The common way is to reset and recreate the selector every time in the outer loop, and have a separate collection of the connected clients (e.g. a std::vector).



来源:https://stackoverflow.com/questions/14687046/sfml-tcp-packet-receive

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!