I programmed a pong multiplayer game using SFML, where i used sf::UdpSockets for transferring data between two PCs. It worked great. Next i wanted to check out how the result would look like if i used the asio network library for networking instead of the SFML Network-classes.
Here my first big issue was, that asio does not provide a class similar to sf::Packet that helps with serializing the data.
With SFML its so beautifully simple, for example if you want to store an enum and some data that belongs to the enum, you could just do:
enum class CommandsToServer{
Connect, // empty
Disconnect, // empty
Data // Vector2f
};
...
sf::Packet packet;
packet << static_cast<uint8_t>(CommandsToServer::Data);
packet << x << y;
and send the packet to the server, where you unpack the content the same way you put it in.
uint8_t command;
uint8_t x, y;
// ... receive packet from socket ...
receivedPacket >> command >> x >> y;
CommandToServer commandToServer = static_cast<CommandToServer>(command);
Since i did not find a straightforward way to pack different types into an array, i just used sf::Packet again with the asio::ip::udp::socket.
This approach looks like this:
m_packet << static_cast<uint8_t>(5);
m_packet << static_cast<uint8_t>(6);
m_socket.send_to(asio::buffer(m_packet.getData(), m_packet.getDataSize()), m_serverEndpoint);
So i just try to transfer two values over the network: 5 and 6.
On the server-side i use
std::array<char, 256> m_receiveBuffer;
...
// in some function
m_socket.async_receive_from(
asio::buffer(m_receiveBuffer), m_remoteEndpoint,
std::bind(&Server::handle_receive, this,
std::placeholders::_1,
std::placeholders::_2));
...
void Server::handle_receive(const asio::error_code &error, std::size_t l_receivedBytes) {
sf::Packet packet;
std::cout << "received bytes: " << int(l_receivedBytes) << "\n"; // Output: received bytes 2
packet.append(m_receiveBuffer.data(), l_receivedBytes);
int num1; int num2;
packet >> num1 >> num2;
std::cout << num1 << ", " << num2 << ".\n"; // Output: 0, 0
receiveData();
Console prints 0, 0. But if i start the debugger and set a breakpoint at the last std::cout-statement, i can see that
packet has the following members:
m_data
[ 0 ] = {char}5 '\005'
[ 1 ] = {char}6 '\006’
m_readPos = 0
m_sendPos = 0
m_isValid = false
Its strange because the values 5 and 6 have apparently been transferred successfully, since they are stored in the std::vector<char> container of sf::Packet. However, they don't get transferred via the >> operator into the variables num1 and num2. I don't know the reason why i cannot transfer the data out of the sf::Packet into the variables on the server-side.