How do i ( or can i?) connect RakNet clients with boost::asio or other then RakNet Server UDP

Started by
3 comments, last by umen242 7 years, 8 months ago

Hello all

i trying to connect raknet client to boost::asio server , using examples from both raknet and boost asio

i saw that RakNet is using its own protocol , which it is expecting to be on the server also , is it the RakNet Way ?
can rakNet Connect and work with other servers for example boost::asio or other ?
Here is the examples

Server :


//
// async_udp_echo_server.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//


#include <cstdlib>
#include <iostream>
#include <boost/asio.hpp>


using boost::asio::ip::udp;


class server
{
public:
    server(boost::asio::io_service& io_service, short port)
        : socket_(io_service, udp::endpoint(udp::v4(), port))
    {
        do_receive();
    }


    void do_receive()
    {
        socket_.async_receive_from(
            boost::asio::buffer(data_, max_length), sender_endpoint_,
            [this](boost::system::error_code ec, std::size_t bytes_recvd)
        {
            if (!ec && bytes_recvd > 0)
            {
                do_send(bytes_recvd);
            }
            else
            {
                do_receive();
            }
        });
    }


    void do_send(std::size_t length)
    {
        socket_.async_send_to(
            boost::asio::buffer(data_, length), sender_endpoint_,
            [this](boost::system::error_code /*ec*/, std::size_t /*bytes_sent*/)
        {
            do_receive();
        });
    }


private:
    udp::socket socket_;
    udp::endpoint sender_endpoint_;
    enum { max_length = 1024 };
    char data_[max_length];
};


int main(int argc, char* argv[])
{
    try
    {
        if (argc != 2)
        {
            std::cerr << "Usage: async_udp_echo_server <9991>\n";
            return 1;
        }


        boost::asio::io_service io_service;


        server s(io_service,9991);


        io_service.run();
    }
    catch (std::exception& e)
    {
        std::cerr << "Exception: " << e.what() << "\n";
    }


    return 0;
}

And this is the RakNet client :


void RakNetWrapper::Init()
{
    char str[512];
    strcpy(str, "127.0.0.1");
    RakNet::SocketDescriptor sd;
    RakNet::StartupResult startupResult = peer->Startup(1, &sd, 1);
    RakNet::ConnectionAttemptResult connectionAttemptResult = peer->Connect(str, SERVER_PORT, 0, 0);
    StartReciveLoop();
}


void RakNetWrapper::StartReciveLoop()
{
    while (1)
    {
        for (packet = peer->Receive(); packet; peer->DeallocatePacket(packet), packet = peer->Receive())
        {
            switch (packet->data[0])
            {
            case ID_REMOTE_DISCONNECTION_NOTIFICATION:
                log("Another client has disconnected.\n");
                break;
            case ID_REMOTE_CONNECTION_LOST:
                log("Another client has lost the connection.\n");
                break;
            case ID_REMOTE_NEW_INCOMING_CONNECTION:
                log("Another client has connected.\n");
                break;
            case ID_CONNECTION_REQUEST_ACCEPTED:
            {
                log("Our connection request has been accepted.\n");


                // Use a BitStream to write a custom user message
                // Bitstreams are easier to use than sending casted structures, and handle endian swapping automatically
                RakNet::BitStream bsOut;
                bsOut.Write((RakNet::MessageID)ID_GAME_MESSAGE_1);
                bsOut.Write("Hello world");
                peer->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
            }
            break;
            case ID_NEW_INCOMING_CONNECTION:
                log("A connection is incoming.\n");
                break;
            case ID_NO_FREE_INCOMING_CONNECTIONS:
                log("The server is full.\n");
                break;
            case ID_DISCONNECTION_NOTIFICATION:
                {
                    log("We have been disconnected.\n");
                }
                break;
            case ID_CONNECTION_LOST:
                {
                    log("Connection lost.\n");
                    
                }
                break;


            case ID_GAME_MESSAGE_1:
            {
                RakNet::RakString rs;
                RakNet::BitStream bsIn(packet->data, packet->length, false);
                bsIn.IgnoreBytes(sizeof(RakNet::MessageID));
                bsIn.Read(rs);
                log("%s\n", rs.C_String());
            }
            break;


            default:
                log("Message with identifier %i has arrived.\n", packet->data[0]);
                break;
            }
        }
    }
}

As you can see the Raknet is using its own protocol inside packet , and expect to receive in the first bit some of the Resopnses in the switch case .
How can i use boost::asio with RakNet ?
Thanks

Advertisement
Both sides of any communication must speak the same prototocl.
This is always the case, no matter what the application.
The web builds on the HTTP protocol, which clients and servers know.
The phone system builds on the SS-7 protocol, which phones and exchanges know.
Digital TV broadcast builds on the ATSC protocol (in the US) which both broadcasters and TV sets know.

There is also the notion of protocol "layering" (see "the OSI model")

The good news with protocols is that one side of the connection has no idea how the other side is implemented, only that the packets on the network conform to the format that's specified by the protocol.
Thus, if you implement the RakNet packet format ("protocol data units" or "PDUs" in generic network parlance) using ASIO, then the RakNet library on the other side will be fine.
That being said, doing so is a fair amount of work -- why not just use RakNet on both sides?
If you use something lower-level, like ASIO or raw sockets, you will have to re-implement all the features you need out of RakNet anyway.
enum Bool { True, False, FileNotFound };

Yeah i know all that , Thanks ,
I was wandering if someone did it already .
what ashame that this great lib don't have any support

what ashame that this great lib don't have any support


It was commercially supported for a long time, but then the guy got hired by Facebook and they open sourced the library.
I think open source is better than just dropping it on the floor :-)
enum Bool { True, False, FileNotFound };

Yes you totally right , im testing enet now .

This topic is closed to new replies.

Advertisement