zoukankan      html  css  js  c++  java
  • Boost Asioserver使用

    今天主要想说道说道boost里面的网络通信库怎样设计和使用,由于近期一直在和网络一起工作,大数据处理和机器学习都离不开最后使用网络进行上线部署。先看看所有的源码吧。

    #include <cstdlib>
    #include <iostream>
    #include <memory>
    #include <utility>
    #include <boost/asio.hpp>
    #include <stdint.h>
    #include "data.h"
    #include <ostream>
    #include <boost/archive/binary_iarchive.hpp>
    #include <boost/archive/binary_oarchive.hpp>
    
    using boost::asio::ip::tcp;
    
    class session
    	: public std::enable_shared_from_this < session >
    {
    public:
    	session(boost::asio::ip::tcp::socket socket)
    		: socket_(std::move(socket))
    	{
    	}
    
    	void start()
    	{
    		do_read();
    	}
    
    private:
    	void do_read()
    	{
    		auto self(shared_from_this());
    
    		//int32_t data_length;
    		boost::asio::async_read(socket_, 
    			boost::asio::buffer(&data_length, 4),
    			[this, self](boost::system::error_code ec, std::size_t length)
    		{
    			if (!ec)
    			{
    				do_read_body();
    			}
    		});
    	}
    	void do_read_body()
    	{
    		
    		auto self(shared_from_this());
    		boost::asio::async_read(socket_,
    			buf_, boost::asio::transfer_exactly(data_length),
    			[this, self](boost::system::error_code ec, std::size_t length)
    		{
    			std::cout << length<<std::endl;
    			if (!ec)
    			{
    				ProcessMessage();
    				do_read();
    			}
    			else
    			{
    				std::cout << "error" << std::endl;
    			}
    		});
    	};
    
    	void ProcessMessage()
    	{
    		boost::archive::binary_iarchive ia(buf_);
    		translate_data message;
    		ia >> message;
    		std::cout << message.width<<std::endl;
    	};
    
    
    	int32_t data_length;
    
    	boost::asio::ip::tcp::socket socket_;
    
    	boost::asio::streambuf buf_;
    };
    
    class server
    {
    public:
    	server(boost::asio::io_service& io_service, short port)
    		: acceptor_(io_service, boost::asio::ip::tcp::endpoint(tcp::v4(), port)),
    		socket_(io_service)
    	{
    		do_accept();
    	}
    
    private:
    	void do_accept()
    	{
    		acceptor_.async_accept(socket_,
    			[this](boost::system::error_code ec)
    		{
    			if (!ec)
    			{
    				std::make_shared<session>(std::move(socket_))->start();
    			}
    
    			do_accept();
    		});
    	}
    
    	boost::asio::ip::tcp::acceptor acceptor_;
    	boost::asio::ip::tcp::socket socket_;
    };
    
    int main(int argc, char* argv[])
    {
    	try
    	{
    		/*if (argc != 2)
    		{
    			std::cerr << "Usage: async_tcp_echo_server <port>
    ";
    			return 1;
    		}*/
    
    		boost::asio::io_service io_service;
    
    		server s(io_service, 8888);
    
    		io_service.run();
    	}
    	catch (std::exception& e)
    	{
    		std::cerr << "Exception: " << e.what() << "
    ";
    	}
    
    	return 0;
    }
    
    这个就是服务区的所有源码。

    data是消息的数据格式,translate_data 这个类的定义,该类能够使用boost进行序列化。整个消息处理起来很的流畅,能够使得我们仅仅关心数据流,而忽略server怎样异步接收消息。当然我的演示样例代码中的数据格式很之简单,数据包开头的int表示数据有多少个字节。索性连我的消息代码一起放出来:

    #include <boost/serialization/array.hpp>
    #include <boost/serialization/vector.hpp>
    
    struct MeasurementZ
    {
    	double m_a[3];
    	double m_w[3];
    	double m_t;
    	friend class boost::serialization::access;
    
    	template<class Archive>
    	void serialize(Archive& ar, const unsigned int version)
    	{
    		ar & boost::serialization::make_array(m_a, 3 * sizeof(double));
    		ar & boost::serialization::make_array(m_w, 3 * sizeof(double));
    		ar & m_t;
    	}
    };
    
    struct translate_data
    {
    	int width;
    	int height;
    	double mt;
    	int N;
    	unsigned char* buffer;//640*480;
    	
    	std::vector<MeasurementZ> z;
    	std::vector<double> Quaterniond;//4
    	std::vector<double> Vector3d;//3
    	double M_rM_t;
    };
    BOOST_SERIALIZATION_SPLIT_FREE(translate_data)
    namespace boost
    {
    	namespace serialization
    	{
    		/** Serialization support for cv::Mat */
    		template<class Archive>
    		void save(Archive & ar, const translate_data& m, const unsigned int version)
    		{
    			ar & m.width;
    			ar & m.height;
    			ar & m.mt;
    			ar & m.N;
    			
    			const size_t data_size = m.width * m.height*sizeof(unsigned char);
    			ar & boost::serialization::make_array(m.buffer, data_size);
    			ar & m.z;
    			ar & m.Quaterniond;
    			ar & m.Vector3d;
    			ar & m.M_rM_t;
    		}    /** Serialization support for cv::Mat */
    		template <class Archive>
    		void load(Archive & ar, translate_data& m, const unsigned int version)
    		{
    			ar & m.width;
    			ar & m.height;
    			ar & m.mt;
    			ar & m.N;
    
    			const size_t data_size = m.width * m.height*sizeof(unsigned char);
    			m.buffer = new unsigned char[m.width*m.height];
    			ar & boost::serialization::make_array(m.buffer, data_size);
    			ar & m.z;
    			ar & m.Quaterniond;
    			ar & m.Vector3d;
    			ar & m.M_rM_t;
    		}
    	}
    };


    整个project很easy,请有用c++11标准来完毕。

  • 相关阅读:
    将博客部署到k3s中
    docker/docker swarm学习
    windows共享文件夹使用中的问题(SMB协议)
    洛谷P1280 尼克的任务 题解 动态规划/最短路
    CF1B.Spreadsheets(电子表格) 题解 模拟
    洛谷P1595 信封问题 题解 错排问题
    洛谷P1809 过河问题 经典贪心问题
    CF1238E.Keyboard Purchase 题解 状压/子集划分DP
    洛谷P2719 搞笑世界杯 题解 概率DP入门
    Treap(树堆)入门
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6901898.html
Copyright © 2011-2022 走看看