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

Started by
1 comment, last by Heelp 7 years, 6 months ago

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:

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.

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:

This topic is closed to new replies.

Advertisement