boost的asio提供了无锁队列和协程。基于这两者可以搭建一个用于基础通讯的tcp服务器。TCP服务器可以自己创建连接连接外部主机也可以在本地端口监听并形成回话。
首先定义接口:
#pragma once
#include <vector>
#include <string>
#include "ht_memory.h"
#include "ts_ptr.hpp"
namespace ht_tcp
{
struct data
{
int i_conn_id;
int i_sesson_id; // 会话ID
};
class i_session
{
public:
enum e_status
{
e_status_dead = 0,
e_status_read_exit = 1,
e_status_write_exit = 2,
e_status_disconnected = 4,
e_status_connected = 8,
e_status_reconnect = 16
};
public:
std::string str_ip_addr;
virtual int write(const char* sz_buf, const int& i_len) = 0;
virtual int read(ht_memory& mry_out) = 0;
virtual e_status status() const = 0;
};
class session_mgr
{
private:
std::vector<ts_ptr<i_session> > m_vec_sessions;
public:
session_mgr();
};
};
inline bool match_flag(const unsigned int& u_value, const unsigned int& u_flag)
{
return (u_value & u_flag) == u_flag;
}
inline unsigned int set_flag(const unsigned int& u_value, const unsigned int& u_flag)
{
return u_value | u_flag;
}
inline unsigned int unset_flag(const unsigned int& u_value, const unsigned int& u_flag)
{
return u_value & (u_flag ^ unsigned int(-1));
}
这里定义了一个可写入可读出的接口。接着,我们实现这个接口,首先是监听类或会,代码如下:
#pragma once
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/lockfree/queue.hpp>
#include <boost/lockfree/policies.hpp>
using namespace boost;
using namespace boost::asio;
using namespace boost::system;
#include "ht_memory.h"
#include "tcp_mgr.h"
class tcp_listen :public ht_tcp::i_session
{
private:
typedef ip::tcp::acceptor acceptor_type;
typedef ip::tcp::endpoint endpoint_type;
typedef ip::tcp::socket socket_type;
boost::lockfree::queue<ht_memory*> m_q_read, m_q_write;
volatile int m_status;
io_service* m_p_ios;
socket_type m_sock;
std::atomic<int> m_rsize, m_wsize;
public:
tcp_listen(const unsigned short& us_port, io_service* p_ios);
~tcp_listen();
virtual int write(const char* sz_buf, const int& i_len);
virtual int read(ht_memory& mry_out);
virtual e_status status() const;
void spawn_read();
void spawn_write();
};
监听类会话定义代码如下:
#include "tcp_listen.h"
#include <vector>
#include <iostream>
#include <boost/chrono.hpp>
#include <boost/asio/steady_timer.hpp>
tcp_listen::tcp_listen(const unsigned short& us_port, io_service* p_ios)
:m_status(e_status_disconnected)
, m_q_read(1024), m_q_write(1024)
, m_p_i