• Advertisement
Sign in to follow this  

Problem when trying to send a packet in UDP - SFML

This topic is 2356 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
ok guys i Changed the line for the server code from


SendPacket >> PersonData1;

to
SendPacket << PersonData1;

also i Changed the line for the client code from


if (ReceivePacket << PersonData2)
to
if (ReceivePacket >> PersonData2)

and here is the final code
[size="4"]
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;

while (true)
{
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;
}


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;

std::cout << "Press Enter to send packet." <<std::endl;
getchar();

char input = getchar();

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

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

input = getchar();
if(input == 'z')
break;
}
Server.Close();
}

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


But the problem now is that the client shows "Could not Receive data. Please this thing is driving me crazy i spent more than 11 hours now researching and looking at other people code trying to fix it, but i just cant.
the SFML TCP example works but i want use UDP

Share this post


Link to post
Share on other sites
Which status code is returned if it's not sf::Socket::Done?




Does this directly happen or does it take some time, before the message is printed?


Share this post


Link to post
Share on other sites

Which status code is returned if it's not sf::Socket::Done?


Socket status: 3 which is Error.


Does this directly happen or does it take some time, before the message is printed?


well when i run the server i press Enter 3 times till it gives me Socket status: 3

Share this post


Link to post
Share on other sites
I think something is wrong with your brackets:







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

input = getchar();
if(input == 'z')
break;
}
Server.Close();





so the while loop only contains the if statement.




You could also post here:


http://www.sfml-dev.org/forum/index.php




Laurent (the sfml developer) usually answers very quickly and can help very good :-)

Share this post


Link to post
Share on other sites

char input = getchar();
...

while(input == 10)


Enter generally translates to 13, not 10, on Windows.

Other than that, I highly recommend putting breakpoints in your source code, and stepping through the client, or server, one line at a time, verifying what the values of the different variables are. A debugger is a valuable tool that you need to use to get insight into the behavior of your program!

Share this post


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

  • Advertisement