Jump to content
  • Advertisement
Sign in to follow this  
FantasyVI

Problem when trying to send a packet in UDP - SFML

This topic is 2445 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[size="5"]Read post #11 for update

---------------------------------------------------------------------------------------------------
Hello eveyone
I'm trying to send some data from a server to a client but when the client receive that data its not the same data that i send, its different or corrupted somehow

[size="4"]Here what the server sends
Age: 12 Name: Bill Hight: 1.32f

[size="4"]Here what the client receives
Age: 52428 Name: -blank- Hight: -1.07374e+008

Why is that ?!!

here is the code

Server

#include <SFML\Network.hpp>
#include <iostream>

struct PersonData
{
sf::Uint16 Age;
std::string Name;
float Height;
};

sf::Packet& operator <<(sf::Packet& Packet, const PersonData& PD)
{
return Packet << PD.Age << PD.Name << PD.Height;
}

sf::Packet& operator >>(sf::Packet& Packet, PersonData& PD)
{
return Packet >> PD.Age >> PD.Name >> PD.Height;
}

void RunServer(unsigned short Port)
{
std::cout<<"write ip address of client you want to send data to ";
std::string IP;
std::cin >> IP;
sf::IPAddress Address(IP);

sf::SocketUDP Server;
sf::Packet SendPacket;

PersonData PersonData1 = {12, "Bill", 1.32f};

SendPacket >> PersonData1;
if (Server.Send(SendPacket,IP ,Port) != sf::Socket::Done)
{
std::cout<<"Could not send data";
}
}

int main()
{

RunServer(4567);
system("pause");
return 0;
}



Client

#include <SFML\Network.hpp>
#include <iostream>

struct PersonData
{
sf::Uint16 Age;
std::string Name;
float Height;
};

sf::Packet& operator <<(sf::Packet& Packet, const PersonData& PD)
{
return Packet << PD.Age << PD.Name << PD.Height;
}

sf::Packet& operator >>(sf::Packet& Packet, PersonData& PD)
{
return Packet >> PD.Age >> PD.Name >> PD.Height;
}

void RunClient()
{
sf::SocketUDP Client;

if (!Client.Bind(4567))
{
std::cout<<"Could not listen";
}

sf::IPAddress Address;
unsigned short Port;
sf::Packet ReceivePacket;

if (Client.Receive(ReceivePacket, Address, Port) != sf::Socket::Done)
{
std::cout<<"Could not Receive data";
}
PersonData PersonData2;
if (ReceivePacket << PersonData2)
{
std::cout << "Age: " << PersonData2.Age << "Name: " << PersonData2.Name << "Hight: "<< PersonData2.Height << std::endl;
}

Client.Close();
}

int main()
{
RunClient();
system("pause");
return 0;
}


sorry for being a newbie and any help is much appreciated.

Share this post


Link to post
Share on other sites
Advertisement
In your client code replace

if (ReceivePacket << PersonData2)

with

if (ReceivePacket >> PersonData2)

Share this post


Link to post
Share on other sites
hm.. I am not familiar with the library but I doubt you can send a structure with a "string" inside. I'd guess you need to replace it with a standard char array.

Share this post


Link to post
Share on other sites

In your client code replace

if (ReceivePacket << PersonData2)

with

if (ReceivePacket >> PersonData2)




well that doesnt work, the client connect with the sever but no data get received from the server.


hm.. I am not familiar with the library but I doubt you can send a structure with a "string" inside. I'd guess you need to replace it with a standard char array.


yes you can send strings. even if you couldnt i still get weird numbers when i use float or int.

Share this post


Link to post
Share on other sites
I'm pretty sure you have your streaming operators the wrong way around.
When preparing a packet to send you do
sf::Packet SendPacket;
PersonData PersonData1 = {12, "Bill", 1.32f};
SendPacket >> PersonData1;
which creates an empty packet, then creates and initializes a PersonData structure and then writes the empty contents of the Packet over the just initialized PersonData.
What you want is
sf::Packet SendPacket;
PersonData PersonData1 = {12, "Bill", 1.32f};
SendPacket << PersonData1;


Similarly, on the client side you do
PersonData PersonData2;
if (ReceivePacket << PersonData2)
{
std::cout << "Age: " << PersonData2.Age << "Name: " << PersonData2.Name << "Hight: "<< PersonData2.Height << std::endl;
}

which successfully creates an empty PersonData, writes the non-initialized contents into the packet and then prints the non-initialized values. You more likely want
PersonData PersonData2;
if (ReceivePacket >> PersonData2)
{
std::cout << "Age: " << PersonData2.Age << "Name: " << PersonData2.Name << "Hight: "<< PersonData2.Height << std::endl;
}


By the way, I dislike overloading the streaming operator for exactly this reason. It appears very intuitive, but it becomes a mess when two people think two different ways are intuitive. I prefer "Structure.Pack(Packet& Target)" and "Packet.Extract(Structure& Target)" structures because they say what they do in the name.

I hope that helps.

Share this post


Link to post
Share on other sites

I'm pretty sure you have your streaming operators the wrong way around.
When preparing a packet to send you do
sf::Packet SendPacket;
PersonData PersonData1 = {12, "Bill", 1.32f};
SendPacket >> PersonData1;
which creates an empty packet, then creates and initializes a PersonData structure and then writes the empty contents of the Packet over the just initialized PersonData.
What you want is
sf::Packet SendPacket;
PersonData PersonData1 = {12, "Bill", 1.32f};
SendPacket << PersonData1;


Similarly, on the client side you do
PersonData PersonData2;
if (ReceivePacket << PersonData2)
{
std::cout << "Age: " << PersonData2.Age << "Name: " << PersonData2.Name << "Hight: "<< PersonData2.Height << std::endl;
}

which successfully creates an empty PersonData, writes the non-initialized contents into the packet and then prints the non-initialized values. You more likely want
PersonData PersonData2;
if (ReceivePacket >> PersonData2)
{
std::cout << "Age: " << PersonData2.Age << "Name: " << PersonData2.Name << "Hight: "<< PersonData2.Height << std::endl;
}


By the way, I dislike overloading the streaming operator for exactly this reason. It appears very intuitive, but it becomes a mess when two people think two different ways are intuitive. I prefer "Structure.Pack(Packet& Target)" and "Packet.Extract(Structure& Target)" structures because they say what they do in the name.

I hope that helps.


thankx for replaying.

yes i thought of that but the problem if i do that the client doesnt connect to the server at all, and when i run the client, the CMD just stays empty like its waiting for the server to connect. thats why i did it like this SendPacket >> PersonData1 . when i do it like this the client recivie data but its not correct data, which is very weird.

any other ideas

btw how do you this ( "Structure.Pack(Packet& Target)" and "Packet.Extract(Structure& Target)" structures ) i'm a newbie when it comes to networking, can you give me an example code that i can but in my program?

Share this post


Link to post
Share on other sites

thankx for replaying.

yes i thought of that but the problem if i do that the client doesnt connect to the server at all, and when i run the client, the CMD just stays empty like its waiting for the server to connect. thats why i did it like this SendPacket >> PersonData1 . when i do it like this the client recivie data but its not correct data, which is very weird.

any other ideas

btw how do you this ( "Structure.Pack(Packet& Target)" and "Packet.Extract(Structure& Target)" structures ) i'm a newbie when it comes to networking, can you give me an example code that i can but in my program?

I went to the tutorials page of SFML and downloaded the tutorial's source code. It has a small program in it that can run either as a server of client and shows you how to wait for a client to connect as a server and then check the server for new messages as a client. See the attached file. Refer to the tutorial and the documentation of SFML to see how the functions work. I actually have no idea. ;)

Share this post


Link to post
Share on other sites

I went to the tutorials page of SFML and downloaded the tutorial's source code. It has a small program in it that can run either as a server of client and shows you how to wait for a client to connect as a server and then check the server for new messages as a client. See the attached file. Refer to the tutorial and the documentation of SFML to see how the functions work. I actually have no idea. ;)

i have actully seen this and its using TCP connection. i have worked for the past 5 hours (not kidding) trying to modify it to work with UDP connection but it didnt work as i hoped. and i have posted the modified code which is the one i'm having problem with xD

Share this post


Link to post
Share on other sites
First make sure, that the right thing is sent.

Change the line for the server code from

SendPacket >> PersonData1;

to

SendPacket << PersonData1;

and verify with the debugger that everything is written as it should be.




Then when receiving make sure that you use the right operator, it must be

Packet >> Struct and not the other way round.

Your code looks quite ok except for the wrong operators.

Try it again with the right operators for both client and server and tell us what happens.

If you have problem, use the debbuger and maybe post the new code here.

Share this post


Link to post
Share on other sites

By the way, I dislike overloading the streaming operator for exactly this reason.


The order of operators is also undefined per standard. So one would need to do this:{
Packet p;
p << a;
p << b;
p << c;
return p;
}
// or
(((p << a) << b) << c); // not sure if this works

I don't know if there are compilers that don't respect expected left-to-right evaluation.


Overloading operators this way is not a problem per se, it's even idiomatic and falls in line with function overloading. Added benefit is that it can be seamlessly piped to any iostream, perhaps for debugging or logging, useful for third-party libraries.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!