使用boost库序列化传输对象

  使用boost库序列化传输对象,要用到boost中的Boost.Serialization

(一)编译boost

并不是说要用到boost都要对boost进行编译,只有用到以下库时才需要编译,刚好我们要用Serialization,所以要进行编译

The only Boost libraries that must be built separately are:

A few libraries have optional separately-compiled binaries:

  • Boost.DateTime has a binary component that is only needed if you're using its to_string/from_string or serialization features, or if you're targeting Visual C++ 6.x or Borland.
  • Boost.Graph also has a binary component that is only needed if you intend to parse GraphViz files.
  • Boost.Math has binary components for the TR1 and C99 cmath functions.
  • Boost.Random has a binary component which is only needed if you're using random_device.
  • Boost.Test can be used in “header-only” or “separately compiled” mode, although separate compilation is recommended for serious use.

那怎么对boost进行编译呢:

Issue the following commands in the shell (don't type $; that represents the shell's prompt):

$ cd path/to/boost_1_51_0
$ ./bootstrap.sh --help

Select your configuration options and invoke ./bootstrap.sh again without the --help option. Unless you have write permission in your system's /usr/local/ directory, you'll probably want to at least use

$ ./bootstrap.sh --prefix=path/to/installation/prefix

to install somewhere else. Also, consider using the --show-libraries and --with-libraries=library-name-list options to limit the long wait you'll experience if you build everything. Finally,

$ ./b2 install

will leave Boost binaries in the lib/ subdirectory of your installation prefix. You will also find a copy of the Boost headers in the include/ subdirectory of the installation prefix, so you can henceforth use that directory as an #include path in place of the Boost root directory.

      选择一个路径,把prefix改成你想要的文件夹名,这样就把boost库编译到了那个文件夹中了(编译的过程大概要用10分钟吧)

      然后在/usr/lib创建一个软链接

  ln -s /home/lei/mylib/prefix/lib/libboost_serialization.so /usr/lib/libboost_serialization.so
       ln -s /home/lei/mylib/prefix/lib/libboost_system.so.1.51.0 /usr/lib/libboost_system.so.1.51.0
      注意这时要用到上面两个动态链接库

      这样编译时加上-lboost_serialization 同时包含相应的头文件,就可以boost中用来序列化的库了~~

  更多资料:boost库网站上的介绍

(二)编写自己的消息结构

以下是我编写的一个简单的消息结构

#ifndef MESSAGE_H

#define MESSAGE_H



#include <string>

//serialization

#include <boost/archive/text_oarchive.hpp>

//deserialization

#include <boost/archive/text_iarchive.hpp>



using std::string;



//message type

enum MessageOption

{

    Login,

    Logout,

    SendToAll,

    PrivateChat

};



struct Message

{

    friend class boost::serialization::access;



    //use this function to serialize and deserialize object

    template<class Archive>

    void serialize(Archive & ar, const unsigned int version)

    {

        ar & sender & receiver & message & option;

    }



    string sender;

    string receiver;

    string message;

    MessageOption option;

};



#endif

注意编写class或者struct时要编写serialize函数

接下来是序列化与反序列化的方法

#ifndef SERIALIZE_H

#define SERIALIZE_H



#include <string>

#include "Message.h"



class Serialization

{

    public:

        static std::string Serialize(const Message& msg);

        static Message DeSerialize(const std::string& message);

};



#endif
#include "Serialization.h"

#include <sstream>



std::string Serialization::Serialize(const Message& msg)

{

    std::ostringstream archiveStream;

    boost::archive::text_oarchive archive(archiveStream);

    archive<<msg;

    return archiveStream.str();

}



Message Serialization::DeSerialize(const std::string& message)

{

    Message msg;

    std::istringstream archiveStream(message);

    boost::archive::text_iarchive archive(archiveStream);

    archive>>msg;

    return msg;

}

(三)处理消息

刚才编写的那个消息结构里面有个option,通过这个option我们就可以知道这个对方发过来的消息是要干嘛的

以下是服务器处理客户端消息的函数

template<typename T>

void EpollServerSocket<T>::ProcessMessage(Socket& clientSocket)

{

    std::string message;

    ReceiveMessage(clientSocket,message);

    T msgStruct=Serialization::DeSerialize(message);



    switch(msgStruct.option)

    {

        case Login :

            SendMessage(clientSocket,"Login_Success");

            break;



        case Logout:

            SendMessage(clientSocket,"Logout_Success");

            DeleteClient(clientSocket.GetSocketfd());

            break;



        case SendToAll:

            SendToAllUsers(msgStruct.message);

            break;

  
        //messages of other type……

        default: break;
} }

通过switch语句来判断消息的类型,个人觉得还是比较简洁的

boost库中有很多东西可以学习,像asio(Boost.Asio是一个跨平台的网络及底层IO的C++编程库,它使用现代C++手法实现了统一的异步调用模型。)

以及还有智能指针shared_ptr等等……

你可能感兴趣的:(boost)