Advertisement

sending and receiving struct using eNet and boost.serialization

Started by April 30, 2016 07:19 AM
11 comments, last by brightening-eyes 8 years, 6 months ago

hello,

i want to send/receive packet using eNet and boost.serialization

i'm using enetpp wrapper for eNet and i'm using boost.serialization to serialize the struct

first, this is the first time that i'm working with boost.serialization

but my serialization code is as follows:


//the structure that represents the game data to be sent
typedef struct gamedata
{
const char *username;
const char *password;
int rank;
bool userpass_incorrect;
bool account_not_exist;
const char *mac_address;
const char *hdd_serial;
const char *ip_address;
int x;
int y;
int z;
int health;
bool is_banned;
bool notify;
const char *pm_user;
const char *chat_user;
const char *message;
const char *server_message;
const char *motd;
bool came_online;
bool went_offline;
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar&username;
ar&password;
ar&userpass_incorrect;
ar&account_not_exist;
ar&mac_address;
ar&hdd_serial;
ar&ip_address;
ar&x;
ar&y;
ar&z;
ar&health;
ar&is_banned;
ar&notify;
ar&pm_user;
ar&chat_user;
ar&message;
ar&server_message;
ar&motd;
ar&came_online;
ar&went_offline;
}
}gamedata;

here is another serialize function that i've wrote in order to make it work but it didn't work:


//serialization/deserialization ruteens
template <class Archive>
void serialize(Archive& ar, gamedata *g, const unsigned int version)
{
ar&g->username;
ar&g->password;
ar&g->rank;
ar&g->userpass_incorrect;
ar&g->account_not_exist;
ar&g->mac_address;
ar&g->hdd_serial;
ar&g->ip_address;
ar&g->x;
ar&g->y;
ar&g->z;
ar&g->health;
ar&g->is_banned;
ar&g->notify;
ar&g->pm_user;
ar&g->chat_user;
ar&g->message;
ar&g->server_message;
ar&g->motd;
ar&g->came_online;
ar&g->went_offline;
}

and, this is the overload of operator <<:


//<<operator for our gamedata struct
ostream& operator << (ostream& os, gamedata *g)
{
os<<g->username;
os<<g->password;
os<<g->rank;
os<<g->userpass_incorrect;
os<<g->account_not_exist;
os<<g->mac_address;
os<<g->hdd_serial;
os<<g->ip_address;
os<<g->x;
os<<g->y;
os<<g->z;
os<<g->health;
os<<g->is_banned;
os<<g->notify;
os<<g->pm_user;
os<<g->chat_user;
os<<g->message;
os<<g->server_message;
os<<g->motd;
os<<g->came_online;
os<<g->went_offline;
}

and, i want to load it into stringstream:

(data is the packet data, cl.gd is a pointer to my gamedata struct)


stringstream ss((char *)data);
text_iarchive ia(ss);
ia>>cl.gd;

and this is the code to save it into ostringstream for sending:


ostringstream s;
text_oarchive oa(s);
oa<<cl.gd;

and, these are 2 errors that i've got:


In file included from C:/Dev-Cpp/i686-w64-mingw32/include/boost/serialization/extended_type_info_typeid.hpp:37:0,
from C:/Dev-Cpp/i686-w64-mingw32/include/boost/archive/detail/oserializer.hpp:38,
from C:/Dev-Cpp/i686-w64-mingw32/include/boost/archive/detail/interface_oarchive.hpp:23,
from C:/Dev-Cpp/i686-w64-mingw32/include/boost/archive/detail/common_oarchive.hpp:22,
from C:/Dev-Cpp/i686-w64-mingw32/include/boost/archive/basic_text_oarchive.hpp:29,
from C:/Dev-Cpp/i686-w64-mingw32/include/boost/archive/text_oarchive.hpp:31,
from F:\projects\cpp\missiontime-server\src\main.cpp:7:
C:/Dev-Cpp/i686-w64-mingw32/include/boost/serialization/access.hpp: In instantiation of 'static void boost::serialization::access::serialize(Archive&,
T&, unsigned int) [with Archive = boost::archive::text_iarchive; T = char]':
C:/Dev-Cpp/i686-w64-mingw32/include/boost/serialization/serialization.hpp:68:22: required from 'void boost::serialization::serialize(Archive&, T&, unsigned
int) [with Archive = boost::archive::text_iarchive; T = char]'
C:/Dev-Cpp/i686-w64-mingw32/include/boost/serialization/serialization.hpp:126:14: required from 'void boost::serialization::serialize_adl(Archive&, T&,
unsigned int) [with Archive = boost::archive::text_iarchive; T = char]'
C:/Dev-Cpp/i686-w64-mingw32/include/boost/archive/detail/iserializer.hpp:189:40: required from 'void boost::archive::detail::iserializer<Archive, T>::load_object_data(boost::archive::detail::basic_iarchive&,
void*, unsigned int) const [with Archive = boost::archive::text_iarchive; T = char]'
F:\projects\cpp\missiontime-server\src\main.cpp:335:1: required from here
C:/Dev-Cpp/i686-w64-mingw32/include/boost/serialization/access.hpp:116:9: error: request for member 'serialize' in 't', which is of non-class type 'char'
t.serialize(ar, file_version);
^
C:/Dev-Cpp/i686-w64-mingw32/include/boost/serialization/access.hpp: In instantiation of 'static void boost::serialization::access::serialize(Archive&,
T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = char]':
C:/Dev-Cpp/i686-w64-mingw32/include/boost/serialization/serialization.hpp:68:22: required from 'void boost::serialization::serialize(Archive&, T&, unsigned
int) [with Archive = boost::archive::text_oarchive; T = char]'
C:/Dev-Cpp/i686-w64-mingw32/include/boost/serialization/serialization.hpp:126:14: required from 'void boost::serialization::serialize_adl(Archive&, T&,
unsigned int) [with Archive = boost::archive::text_oarchive; T = char]'
C:/Dev-Cpp/i686-w64-mingw32/include/boost/archive/detail/oserializer.hpp:148:40: required from 'void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&,
const void*) const [with Archive = boost::archive::text_oarchive; T = char]'
F:\projects\cpp\missiontime-server\src\main.cpp:335:1: required from here
C:/Dev-Cpp/i686-w64-mingw32/include/boost/serialization/access.hpp:116:9: error: request for member 'serialize' in 't', which is of non-class type 'char'

now:

compiler: gcc (mingw-w64) 5.3.0 with gnu++14 enabled

boost: 1.60.0

thanks in advance

when you can't see well like me, you can't test your applications and you can't read something

Github

You can't serialize raw pointers. How would Boost know how long each pointed-to array is?
Use std::string if you want to use boost::serialization for strings.
enum Bool { True, False, FileNotFound };
Advertisement

hi again,

it has been fixed!, but why boost.serialization doesn't serialize pointers?

when you can't see well like me, you can't test your applications and you can't read something

Github

Hi. Have a look at google protocol buffers, works well for serializing.

hi again,
it has been fixed!, but why boost.serialization doesn't serialize pointers?

Why would you serialise pointers? The scope of pointer is protected memory.

The way serialisation works is if the serialiser (Archive) knows about the type (meta-data) that is passed to it. Bool, unsigned integer,... Generic types are unambiguous, or objects with methods understood by the serialiser (a component derived to be 'serialisable' for example).

Passing a pointer, it could be a pointer to a single element (a single 'char' for example), a string (in terms of chars, which are null terminated), or an array of an arbitrary number of elements. Then how many elements should be serialised? Where do those arrays get deserislalised into? Who is doing the memory allocation on the receiver end? What if the 'username' string on the deserialiser side is already allocated memory? Will you get a memory leak? What if it points to static data? Static allocation have a fixed size, what is the string/array is bigger than the static allocation?

Questions, questions... When you deal with pointers and address of things, you have to be extra careful.

Containers take care of those problems, and you should be using them when possible, like vectors, lists, strings, maps (dictionaries).

why boost.serialization doesn't serialize pointers?


Because the value of the pointer makes no sense outside your process, and boost::serialization can't know how many elements to serialize if it were to serialize the pointed-at data.

To do that, you have to tell it what to do. Look at:

boost::serialization::binary_object(void * t, size_t size);
and

template <T> boost::serialization::make_array(T* t, std::size_t size);
enum Bool { True, False, FileNotFound };
Advertisement

ok, got it

but when i've changed char *username to std::string username and tried to connect, it crashed (i don't know what i'm doing wrong)

std::string is safe to use and i don't know what is wrong with it!

this is the debug log:

Active debugger config: GDB/CDB debugger:Default
Building to ensure sources are up-to-date
Selecting target:
Debug
Adding source dir: F:\projects\cpp\missiontime\
Adding source dir: F:\projects\cpp\missiontime\
Adding file: F:\projects\cpp\missiontime\bin\Debug\missiontime.exe
Changing directory to: F:/projects/cpp/missiontime/bin/Debug
Set variable: PATH=.;C:\Dev-Cpp\bin;C:\Dev-Cpp;C:\Windows\System32;C:\Windows;C:\Windows\System32\wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files\TortoiseSVN\bin;C:\Program Files\Skype\Phone;C:\Program Files\CMake\bin;C:\Program Files\Heroku\bin;C:\Program Files\Git\cmd;C:\php;C:\ProgramData\ComposerSetup\bin;C:\Users\brightening-eyes\AppData\Roaming\Composer\vendor\bin

[debug]Command-line: C:\Dev-Cpp\bin\gdb.exe -fullname -quiet  -args F:/projects/cpp/missiontime/bin/Debug/missiontime.exe
[debug]Working dir : F:\projects\cpp\missiontime\bin\Debug

Starting debugger: C:\Dev-Cpp\bin\gdb.exe -fullname -quiet  -args F:/projects/cpp/missiontime/bin/Debug/missiontime.exe
done

[debug]> set prompt >>>>>>cb_gdb:

Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Setting breakpoints

[debug]Reading symbols from F:/projects/cpp/missiontime/bin/Debug/missiontime.exe...
[debug]done.
[debug](gdb)
[debug]>>>>>>cb_gdb:
[debug]> show version
[debug]GNU gdb (GDB) 7.10.1
[debug]Copyright (C) 2015 Free Software Foundation, Inc.
[debug]License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
[debug]This is free software: you are free to change and redistribute it.
[debug]There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
[debug]and "show warranty" for details.
[debug]This GDB was configured as "i686-w64-mingw32".
[debug]Type "show configuration" for configuration details.
[debug]For bug reporting instructions, please see:
[debug]<http://www.gnu.org/software/gdb/bugs/>.
[debug]Find the GDB manual and other documentation resources online at:
[debug]<http://www.gnu.org/software/gdb/documentation/>.
[debug]For help, type "help".
[debug]Type "apropos word" to search for commands related to "word".
[debug]>>>>>>cb_gdb:
[debug]> set confirm off

Debugger name and version: GNU gdb (GDB) 7.10.1

[debug]>>>>>>cb_gdb:
[debug]> set width 0
[debug]>>>>>>cb_gdb:
[debug]> set height 0
[debug]>>>>>>cb_gdb:
[debug]> set breakpoint pending on
[debug]>>>>>>cb_gdb:
[debug]> set print asm-demangle on
[debug]>>>>>>cb_gdb:
[debug]> set unwindonsignal on
[debug]>>>>>>cb_gdb:
[debug]> set print elements 0
[debug]>>>>>>cb_gdb:
[debug]> set new-console on
[debug]>>>>>>cb_gdb:
[debug]> set disassembly-flavor intel
[debug]>>>>>>cb_gdb:
[debug]> catch throw
[debug]Catchpoint 1 (throw)
[debug]>>>>>>cb_gdb:
[debug]> source C:\Program Files\CodeBlocks\share\codeblocks/scripts/stl-views-1.0.3.gdb
[debug]>>>>>>cb_gdb:
[debug]> directory F:/projects/cpp/missiontime/
[debug]Source directories searched: F:/projects/cpp/missiontime;$cdir;$cwd
[debug]>>>>>>cb_gdb:
[debug]> run
[debug]Starting program: F:\projects\cpp\missiontime\bin\Debug\missiontime.exe

Child process PID: 8692

[debug][New Thread 8692.0x1f08]
[debug][New Thread 8692.0x13e8]
[debug][New Thread 8692.0x1de8]
[debug][New Thread 8692.0x21e4]
[debug][New Thread 8692.0x2390]
[debug][New Thread 8692.0x1c84]
[debug][New Thread 8692.0x1c7c]
[debug][New Thread 8692.0x20fc]
[debug][New Thread 8692.0x2550]
[debug][New Thread 8692.0x1ee4]
[debug][New Thread 8692.0x19f0]
[debug][New Thread 8692.0x12cc]
[debug][New Thread 8692.0x2694]
[debug][Thread 8692.0x2694 exited with code 0]
[debug][Thread 8692.0x12cc exited with code 0]
[debug][New Thread 8692.0x20ec]
[debug][New Thread 8692.0x22b4]
[debug][Thread 8692.0x22b4 exited with code 0]
[debug][Thread 8692.0x20ec exited with code 0]
[debug]Program received signal SIGSEGV, Segmentation fault.
[debug]0x76f2ab86 in wcsnicmp () from C:\Windows\system32\msvcrt.dll
[debug]>>>>>>cb_gdb:

Program received signal SIGSEGV, Segmentation fault.
In wcsnicmp () (C:\Windows\system32\msvcrt.dll)

[debug]> bt 30
[debug]#0  0x76f2ab86 in wcsnicmp () from C:\Windows\system32\msvcrt.dll
[debug]#1  0x005da89f in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
[debug]#2  0x00000000 in ?? ()
[debug]>>>>>>cb_gdb:

i guess this is from std::string::assign, but i'm not sure

what can be wrong?

and, std::string hold's a pointer from the text!, but it can be serialized!

when you can't see well like me, you can't test your applications and you can't read something

Github

Compile your code with -O0 and -ggdb, and then set a breakpoint before the crashing line, and step through it.

std::string is safe, even though it uses pointers internally, because boost::serialization has a specialization for std::string (and most of the other STL containers.)

Did you look at the binary object and array support functions I recommended? Do you understand how they work and why they're needed? If not, you probably need to read up a bit on how C++ and pointers work in general before you'll be successful doing networking and other systems programming.
enum Bool { True, False, FileNotFound };

i know how pointers are work, but can i serialize pointers with for loop like this?

for (int i=0;i<strlen(text);++i)
{
ar&text[i];
}
i thaught boost.serialization does this automaticly (as i've read from documentation and theboostcpplibraries.com website)
and, this is my first time that i'm using boost.serialization

thanks

when you can't see well like me, you can't test your applications and you can't read something

Github

You can serialize like that, with two changes:

1) You need to write the length of the array first

2) calling strlen() for each comparison in that loop will be unnecessarily inefficient
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement