Jump to content
  • Advertisement
Sign in to follow this  
Heelp

How the information I send via RakNet::BitStream is converted to RakNet::Packet when received?

This topic is 659 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

Guys, the question is very stupid, but I can't figure it out all morning that's why I decided to ask it here.

 

Basically I'm writing the server code for my paintball game, pure client-server model seems the easiest for me, that's why the server just receives gamestates from the clients and then sends some stuff based on what was received.

 

When I receive packets, I do something like this:

    RakNet::Packet *packet = nullptr;

    for( packet = peer->Receive(); packet; peer->DeallocatePacket( packet ), packet = peer->Receive() )
    {

        if( packet->data[ 0 ] == PLAYER_MOVE_FORWARD  ) {send coords }
        if( packet->data[ 0 ] == PLAYER_MOVE_BACKWARD ) { send coords }
        if( packet->data[ 0 ] == PLAYER_MOVE_LEFT     ) { send coords }
        if( packet->data[ 0 ] == PLAYER_MOVE_RIGHT    ) { send coords }
    }

As you can see, when I receive packets, I use the RakNet::Packet structure which looks like this:

namespace RakNet
{
struct Packet
{
/// The system that send this packet.
SystemAddress systemAddress;
/// A unique identifier for the system that sent this packet, regardless of IP address (internal / external / remote system)
/// Only valid once a connection has been established (ID_CONNECTION_REQUEST_ACCEPTED, or ID_NEW_INCOMING_CONNECTION)
/// Until that time, will be UNASSIGNED_RAKNET_GUID
RakNetGUID guid;
/// The length of the data in bytes
unsigned int length;
/// The length of the data in bits
BitSize_t bitSize;
/// The data from the sender
unsigned char* data;
} // Namespace

You can see that in the RakNet::Packet structure there is a systemAddress and some other stuff that I receive.

 

But the problem is I didn't send anything like this.

 

I do the packet sending like this:

    RakNet::BitStream bsOut;
    bsOut.Write( (RakNet::MessageID) gameState );
    peer->Send( &bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true );

So I send a bitstream that contains only one thing and that is the gamestate and nothing else, but then when I receive the message on the other side, I do packet->Receive(). How was my bitstream converted to RakNet::Packet and how does raknet know which data from my bitstream goes to what data in the Raknet::Packet structure when the conversion is made???  :blink:

 

And in the bitstream I just send one thing and that is the gameState variable, I don't send my IP or RaknetGUID, so the server shouldn't know who sent the packet. But in the RakNet::Packet there is a systemAddress field, there is RakNetGUID field, so how are these fields filled with data when I haven't send anything other that gameState in the bitstream?  :huh:

 

Guys, thanks a lot for reading this. And, please, if you have the time and you know the reasons, try to explain this in the simplest way you can, because I'm kind of studying this stuff on my own, and I don't know what I don't know.   :unsure:

Edited by codeBoggs

Share this post


Link to post
Share on other sites
Advertisement

The last parameter for "Send" method:

RakNet::BitStream bsOut;
bsOut.Write( (RakNet::MessageID) gameState );
peer->Send( &bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true );

which you've set to "true" tells the peer to broadcast. So your server sends gameState to every connected client. If you want to send it only to particular one you should set it to "false" and instead of passing "RakNet::UNASSIGNED_SYSTEM_ADDRESS" just pass desired system identifier.

 

Now about question why client knows all this stuff:

struct Packet
{
/// The system that send this packet.
SystemAddress systemAddress;
/// A unique identifier for the system that sent this packet, regardless of IP address (internal / external / remote system)
/// Only valid once a connection has been established (ID_CONNECTION_REQUEST_ACCEPTED, or ID_NEW_INCOMING_CONNECTION)
/// Until that time, will be UNASSIGNED_RAKNET_GUID
RakNetGUID guid;
/// The length of the data in bytes
unsigned int length;
/// The length of the data in bits
BitSize_t bitSize;
/// The data from the sender
unsigned char* data;
} // Namespace

When the other end receives a packet from TCP or UDP protocol (raknet is based on UDP), it immediately knows the IP address and port (systemAddress) of a sender. This is just how UDP/TCP protocol was designed. You never send just pure data. Everything is hidden from you to make things easier. Even RakNet has it's own "ReliabilityLayer" that encapsulates your data. That extra overhead added to your packet contains information about its reliability, data length of your "gameState" etc. RakNet then passes this packet to "Transport Layer" (UDP) and it adds even more data to the packet, so the receiver can know sender ip address and port.

https://en.wikipedia.org/wiki/Encapsulation_(networking)

https://en.wikipedia.org/wiki/OSI_model

https://en.wikipedia.org/wiki/User_Datagram_Protocol

 

When your client receives a packet it just "decapsulates" and reads extra information so it can feed "Packet" structure. That's all story.

Edited by 8artek0v0

Share this post


Link to post
Share on other sites
When the other end receives a packet from TCP or UDP protocol (raknet is based on UDP), it immediately knows the IP address and port (systemAddress) of a sender. This is just how UDP/TCP protocol was designed. You never send just pure data. Everything is hidden from you to make things easier. Even RakNet has it's own "ReliabilityLayer" that encapsulates your data. That extra overhead added to your packet contains information about its reliability, data length of your "gameState" etc. RakNet then passes this packet to "Transport Layer" (UDP) and it adds even more data to the packet, so the receiver can know sender ip address and port. When your client receives a packet it just "decapsulates" and reads extra information so it can feed "Packet" structure. That's all story.

 

This cleared everything up for me. Thanks a lot, 8artek0v0. :cool:

Edited by codeBoggs

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!