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

Author Topic: Values in UDP packets are corrupted  (Read 6264 times)

0 Members and 1 Guest are viewing this topic.

DinoMijatovic

  • Newbie
  • *
  • Posts: 5
    • View Profile
Values in UDP packets are corrupted
« on: January 09, 2014, 06:55:36 pm »
Hey guys, I am making a simple game using SFML. Currently I've just got 2 rectangle shape players that move about. I'm trying to send UDP packets that contain 2 floats that store a client's X and Y positions to a server, which then forwards that very same packet to the other client. I've done a fair bit of debugging, and as far as I can tell, the values in the packet are correct up until the point that they are actually received by a client where, when extracted, the values are 0 and 0. I'm not really sure how to go about fixing this, as I am fairly new to SFML and network programming. I'll post the code that I think is relevant below

server main
//Used to send Player positions between clients
struct playerData
        {
                sf::Vector2f Position;
        };
       
        //Used to store ClientIDs, as well ass their addresses and the ports the client sockets are bound to
        struct clientData
        {
                sf::IpAddress address;
                unsigned short port;
                sf::Uint16 ID;
        };

int main()
{
        clientData clients[2];

        sf::UdpSocket socket;

        sf::Uint16 SocketID = 0;
       
        sf::Packet packet;

        sf::Packet receivedPacket;

        packet << SocketID;

        bool keepRunning = true;

        sf::IpAddress sender;
       
        unsigned short port;

        unsigned short ClientPort;

        //bind the listener to a port;
        if(socket.bind(4444) == sf::Socket::Done)
        {
                //Wait for 2 clients to connect
                for(int i  = 0; i < 2; i++)
                {
                       
                        //When a client connects, it should send a packet containing the port it is bound to
                        //Server stores this in the ClientData struct, as well as the address it received from
                        //and the Client's ID
                        if(socket.receive(packet, sender, port) == sf::Socket::Done)
                        {      
                                packet >> ClientPort;

                                clients[i].address = sender;
                                clients[i].port = ClientPort;
                                clients[i].ID = SocketID;

                                SocketID += 1;

                                packet.clear();


                        }
                }

               
                //Send back the Client's ID
                for(int i = 0; i < 2; i++)
                {
                        packet << clients[i].ID;
                        socket.send(packet, clients[i].address, clients[i].port);
                        packet.clear();

                }

               
                while(keepRunning == true)
                {
                       
                       
                        //Receive a packet containing a client's position in the game world
                        //Then send that same packet to the other client
                       
                        if(socket.receive(packet, clients[1].address, clients[1].port) == sf::Socket::Done)
                        {
                       
                                socket.send(packet, clients[0].address, clients[0].port);
                                cout<<"Sent info to player 2"<<endl;

                                packet.clear();

                        }
                       
                       
                        if(socket.receive(packet, clients[0].address, clients[0].port) == sf::Socket::Done)
                        {

                                socket.send(packet, clients[1].address, clients[1].port);
                                cout<<"Sent info to player 1"<<endl;

                                packet.clear();

                        }
                }


Client class functions:
//Binds the client to a free port, and then stores that port to be sent to the server to be stored
void client::Bind()
{
        bind(myPort);

        myPort = getLocalPort();
}


//sends the client port to server, and in return gets its ID
Uint16 client::getID()
{
        packet << myPort;

        std::cout<<myPort<<std::endl;

        send(packet, serverAddress, port);

        while(gotID == false)
        {

                std::cout<<"waiting..."<<std::endl;
                if(receive(receivedPacket, serverAddress, port) == sf::Socket::Done)
                {
                        receivedPacket>>receivedID;
                        gotID = true;
                }
        }

        setBlocking(false);

        return receivedID;
}

void client::SendPlayerData(Packet packet)
{
        send(packet, serverAddress, port);
}

bool client::ReceivePlayerData(Packet packet)
{      
        if(receive(packet, serverAddress, port) == sf::Socket::Done)
                return true;

}


Client main:
sf::Uint32 OtherX;
sf::Uint32 OtherY;

//used tp send player's position to server
sf::Uint32 Xposition;
sf::Uint32 Yposition;

int main()
{

        client Client;

        player Players[2];

        Players[0].setFillColor(sf::Color::Red);
        Players[1].setFillColor(sf::Color::Blue);

        Players[0].setPosition(200.f, 400.f);
        Players[1].setPosition(300.f, 300.f);

sf::Packet packet;

        sf::Packet Receivedpacket;

       
        Client.Bind();

        Client.getID();
       

        cout<<"gotID"<< Client.receivedID<<endl;

        sf::RenderWindow window(sf::VideoMode(800, 600), "My window");

       

                // run the program as long as the window is open
                while (window.isOpen())
                {
                        // check all the window's events that were triggered since the last iteration of the loop
                        sf::Event event;
                        while (window.pollEvent(event))
                        {
                                // "close requested" event: we close the window
                                if (event.type == sf::Event::Closed)
                                        window.close();
                        }

                        //make sure only this client's player can be controlled by this keyboard
                        Players[Client.receivedID].Movement(Client.receivedID);

                        cout<<"My ID: "<< Client.receivedID<<endl;


                        //Ready this player's data to be sent to the server
                        Xposition = Players[Client.receivedID].getPosition().x;
                        Yposition = Players[Client.receivedID].getPosition().y;

                        packet << Xposition <<Yposition;

                        Client.SendPlayerData(packet);

                        packet.clear();
                       
                       
                        //Receive information about other player
                        if(Client.ReceivePlayerData(Receivedpacket))
                        {
                                Receivedpacket >> OtherX >> OtherY;

                        }

if(Client.receivedID == 1)
                                        Players[0].setPosition(OtherX, OtherY);
                               
                                else if(Client.receivedID == 0)
                                        Players[1].setPosition(OtherX, OtherY);


                                Receivedpacket.clear();
                        }

// clear the window with black color
                        window.clear(sf::Color::Black);
                         
                        // draw everything here...
                        for(int i = 0; i < 2; i++)
                                window.draw(Players[i]);
                       

                        // end the current frame
                        window.display();
                }
       

    return 0;
}

 


Like I said, I'm pretty to new to networking and SFML, so any help at all here is really appreciated :)

Thank you!

P.S. I apologise for the wall of code  :-[

DinoMijatovic

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Values in UDP packets are corrupted
« Reply #1 on: January 09, 2014, 08:35:02 pm »
Anyone got any clue? Not sure how long it usually takes for someone to reply to these things.

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Values in UDP packets are corrupted
« Reply #2 on: January 09, 2014, 09:09:01 pm »
  • Have patience, bumping your post makes no difference here  ;)
  • Use TCP, it will save you lots from lots headaches and other issues
  • http://en.sfml-dev.org/forums/index.php?topic=5559.0
  • As with the link above, you don't need graphics to show minimal code problem with networking - or even a window for that matter
  • Consider using SFNUL (Once you see the power of sfn::SyncedObject you won't turn back  :D)
« Last Edit: January 09, 2014, 09:13:50 pm by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

DinoMijatovic

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Values in UDP packets are corrupted
« Reply #3 on: January 09, 2014, 09:47:14 pm »
Hey, thanks!

Sorry, it's my first time posting, so I may have posted a bit too much stuff. I also definitely structured my question wrong :P

I appreciate you recommending TCP, but I don't want to do TCP just because I gave up on doing UDP. I don't really get anything from that, I really want to try and finish this so that hopefully when I get it working I understand why it works, and can duplicate on a larger project later on. If you're telling me to give up on UDP, at least tell me what I'm doing wrong so that I can walk away from it having learned something new!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Values in UDP packets are corrupted
« Reply #4 on: January 09, 2014, 10:03:11 pm »
What if you send the packets to the localhost?

Debugging approach #3: Try to minimize the code until the you can blame a specific, small part of it for the problem.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

DinoMijatovic

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Values in UDP packets are corrupted
« Reply #5 on: January 09, 2014, 10:59:58 pm »
Quote
What if you send the packets to the localhost?

I've tried that there, I'm still getting the same result.

Quote
Try to minimize the code until the you can blame a specific, small part of it for the problem.

I'm pretty sure that the client receive stuff is where it all goes wrong, as after quite a bit of couts, thats the only time where the values in the packet aren't what were sent.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Values in UDP packets are corrupted
« Reply #6 on: January 09, 2014, 11:27:14 pm »
ReceivePlayerData() should take the parameter by reference. Otherwise, the packet remains local to the function.

But that's something you can find out when using a real debugger (not only cout) ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

DinoMijatovic

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Values in UDP packets are corrupted
« Reply #7 on: January 10, 2014, 12:10:07 am »
Quote
ReceivePlayerData() should take the parameter by reference. Otherwise, the packet remains local to the function.

Thank you so much, this was exactly it. ;D

Mistakes are nothing more than learning experiences, huh?

m4unot

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Values in UDP packets are corrupted
« Reply #8 on: August 29, 2014, 05:17:34 am »
Hi DinoMijatovic,

i'm also new and trying to study your source code, but how did you fix the problem?

can you please show me by code what you changed/replaced to make it work please...

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Values in UDP packets are corrupted
« Reply #9 on: August 29, 2014, 12:57:42 pm »
I kinda doubt his problem will help you, but whatever...

bool client::ReceivePlayerData(Packet packet)

This should be receiving the packet as a reference (not copied).
« Last Edit: August 29, 2014, 01:01:45 pm by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

m4unot

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Values in UDP packets are corrupted
« Reply #10 on: August 30, 2014, 03:58:22 am »
Did he change:
bool client::ReceivePlayerData(Packet packet)

to

bool client::ReceivePlayerData(Packet& packet)

to make it work? if not, please show me example and explain please so i understand it...

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Values in UDP packets are corrupted
« Reply #11 on: August 30, 2014, 04:02:59 am »
Yes  ;)
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor