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

Author Topic: Trying to communicate with packages  (Read 2489 times)

0 Members and 1 Guest are viewing this topic.

renansouzones

  • Newbie
  • *
  • Posts: 5
    • View Profile
Trying to communicate with packages
« on: June 08, 2015, 09:41:16 pm »
Hi everyone!  :D

Well, this is my first time using SFML Network  - actually, that's my first time working on a network project at all. I have no previous experiences handling networks of any kind, so please forgive me if I am asking easy questions.

So: I'm working on a card game and there will be two sides: Server and Client. The Server will be responsible for hosting all players cards and each action performed by them will be sent to the Server. To exchange data between them, I'm using SFML packages.

There is a class named "Jogador" (which stands for "Player" in portuguese) and inside that class there are three instances of another class named "Carta" ("Card"). In other words, each player has three cards. These players are defined inside the Server and then sent to the Client via packages so they can be drawn on the Client's screen. There are also two other main classes: "Servidor" ("Server") and "Controlador" ("Controller", where the game itself will run).

This is the main.cpp so far (questions right below it):

#include <iostream>
#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include "Servidor.h"
#include "Controlador.h"
#include "Jogador.h"

sf::TcpSocket socket;
char conexao;
char buffer[2000];
size_t recebido;

bool eServidor = false;
bool servLoop = false;

sf::Packet& operator <<(sf::Packet& packet, const Jogador& jogador)
{
        return packet << jogador;
}

sf::Packet& operator >>(sf::Packet& packet, const Jogador& jogador)
{
        return packet >> jogador;
}

int main()
{
        Servidor s;

        s.novoTurno(); // this is where the cards of each player are being defined

        sf::Packet j0, j1, j2, j3, j4, j5;                              // each packet represents a player
        j0 << s.getJogador(0);
        j1 << s.getJogador(1);
        j2 << s.getJogador(2);
        j3 << s.getJogador(3);
        j4 << s.getJogador(4);
        j5 << s.getJogador(5);

        std::cout << "Hit (s) for server or (c) for client: \n";
        std::cin >> conexao;

        if (conexao == 's')
        {
                texto += "server";
                eServidor = true;
                servLoop = true;
        }
        else if (conexao == 'c')
        {
                texto += "client";
        }

        if (eServidor == true)
        {
                sf::TcpListener listener;
                listener.listen(2000);
                listener.accept(socket);

                socket.send(j0); // sends all player information to the clients
                socket.send(j1);
                socket.send(j2);
                socket.send(j3);
                socket.send(j4);
                socket.send(j5);
                std::cout << "Cartas enviadas.\n";

                while (servLoop == true)
                {
                       
                }
        }
        else
        {
                socket.connect(sf::IpAddress::getLocalAddress(), 2000);

                Controlador c(width, height, title); // handles client actions

                socket.receive(j0); // receive player data from the server

                Jogador jg;
               
                j0 >> jg;

                c.defineCartas(jg); // defines the client's player data (get from Server)

                while (c.getWindow().isOpen())
                {
                        sf::Event event;

                        while (c.getWindow().pollEvent(event)) 
                        {
                                if (event.type == sf::Event::Closed){ c.getWindow().close(); }

                                eventosMouse(event);

                                c.getWindow().clear();
                                c.abreJogo(); // this is where the cards are being displayed on the screen
                                c.getWindow().display();
                        }
                }
        }
       
        return 0;
}

When trying to execute it, I have a stack overflow error right in the part of the code with the "operator" - in the upper side. I did that coding because I'm sending custom classes through the packages (I saw that on SFML documentation):

sf::Packet& operator <<(sf::Packet& packet, const Jogador& jogador)
{
        return packet << jogador;
}

Did I do something wrong through the code?

Also, if you observed something else I did wrong please notify me as I lack experience on Network area (not only in SFML) and there is a good chance I'm doing something awful. :P

Thanks in advance!
« Last Edit: June 08, 2015, 09:49:08 pm by renansouzones »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Trying to communicate with packages
« Reply #1 on: June 08, 2015, 10:19:37 pm »
Your overload of operator << for Jogador calls operator << with a Jogador. Which calls your overload of operator << for Jogador, which calls operator << with a Jogador. Which calls your overload of operator << for Jogador, which... stack overflow.

The purpose of an operator overload is not to call itself, you must define what happens when "sf::Packet << Jogador" is invoked -- you must decompose it in terms of calls to other operators << which are already defined. Have a look at the tutorial again, it's clearly shown with an example.
Laurent Gomila - SFML developer

renansouzones

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Trying to communicate with packages
« Reply #2 on: June 09, 2015, 03:56:51 am »
I modified the previous operator and changed for this:

class CardPacket : public sf::Packet
{
        virtual const void* onSend(std::size_t& size)
        {
                const void* srcData = getData();
                return srcData;
        }
        virtual void onReceive(const void* data, std::size_t size)
        {
                append(data, size);
        }
};

But now there are errors every time I write something like "CardPacket j0 << s.getJogador(0);". What did I do wrong?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Trying to communicate with packages
« Reply #3 on: June 09, 2015, 07:55:11 am »
The problem here seems to be your lack of knowledge, maybe you should spend more time learning the language and practicing with simpler stuff. No offense, but the code that you write makes no sense, you clearly have no idea of what you're doing. We could give you the solution right now but you would probably not fully understand it, and it wouldn't be different from what the tutorial shows anyway.
Laurent Gomila - SFML developer

renansouzones

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Trying to communicate with packages
« Reply #4 on: June 09, 2015, 07:10:11 pm »
Unfortunately it's going to be really hard to both master network practices and deliver this project in time (as this is supposed to be done by Friday), but I followed your advice and tried to do it less complicated - instead of sending the whole "Carta" class, I'm sending only its values:

int main()
{
        Servidor s;

        sf::Packet j0;
       
        if (eServer == true) // there is a boolean here to set if it's the server or a cliente
        {
                sf::TcpListener listener;
                listener.listen(2000);
                listener.accept(socket);

                s.novoTurno();

// all the values below represent 3 cards with 4 variables each
                j0 << s.getJogador(0).getMaoCartas(0).getNumero() << s.getJogador(0).getMaoCartas(0).getNaipe() << s.getJogador(0).getMaoCartas(0).getValor() << s.getJogador(0).getMaoCartas(0).getImagem() << s.getJogador(0).getMaoCartas(1).getNumero() << s.getJogador(0).getMaoCartas(1).getNaipe() << s.getJogador(0).getMaoCartas(1).getValor() << s.getJogador(0).getMaoCartas(1).getImagem() << s.getJogador(0).getMaoCartas(2).getNumero() << s.getJogador(0).getMaoCartas(2).getNaipe() << s.getJogador(0).getMaoCartas(2).getValor() << s.getJogador(0).getMaoCartas(2).getImagem();
               
                socket.send(j0); // this is where the cards are supposed to be sent

                while (servLoop == true)
                {
                       
                }
        }
        else
        {
                socket.connect(sf::IpAddress::getLocalAddress(), 2000);

                Controlador c(width, height, title); // client's class

                Carta c1, c2, c3;
                int nm1, np1, vl1,
                        nm2, np2, vl2,
                        nm3, np3, vl3;
                std::string im1, im2, im3;

                socket.receive(j0);
       
                j0 >> nm1 >> np1 >> vl1 >> im1 >> nm2 >> np2 >> vl2 >> im2 >> nm3 >> np3 >> vl3 >> im3;

                c1.setNumero(nm1);
                c1.setNaipe(np1);
                c1.setValor(vl1);
                c1.setImagem(im1);
                c2.setNumero(nm2);
                c2.setNaipe(np2);
                c2.setValor(vl2);
                c2.setImagem(im2);
                c3.setNumero(nm3);
                c3.setNaipe(np3);
                c3.setValor(vl3);
                c3.setImagem(im3);
               
                c.getJogador().setMaoCartas(0, c1);
                c.getJogador().setMaoCartas(1, c2);
                c.getJogador().setMaoCartas(2, c3);

                c.defineCartas(); // cards received and stored in client's class

                while (c.getWindow().isOpen())
                {
                        sf::Event event;

                        while (c.getWindow().pollEvent(event))
                        {
                                if (event.type == sf::Event::Closed){ c.getWindow().close(); }

                                eventosMouse(event);

                                c.getWindow().clear();
                                c.abreJogo();
                                c.getWindow().display();
                        }
                }
        }
       
        return 0;
}


The Client part is working just fine, but the Server's isn't. I run the Server and it's listener keep waiting until a Client connect - when it does, the project running the Server crashes and only the Client keeps running (and it obviously can't read the cards because it didn't receive any). Where exactly am I doing wrong?

I understand the problem here is my lack of knowledge and I agree with you. I am reading everything I can about SFML network in the few free time I have, although I face many difficulties understanding this part. The main problem here is the deadline (this Friday) to deliver this, that's why I'm comming to you with these questions. Sorry for any inconvenience. :(
« Last Edit: June 09, 2015, 07:12:20 pm by renansouzones »