boost/asio 异步通讯

基础示例,根据客户端发送的消息,再原样返回
main.cpp


#include <iostream>
#include<boost/asio.hpp>
#include"Server.h"

int main()
{
    boost::asio::io_context ioc;
    boost::asio::io_context ioc2;

    Server server(ioc,12345);
    std::cout<<"Server started"<<std::endl;
    while (1);
    return 0;
}


Session.h

#pragma once
#include<boost/asio.hpp>
#include<queue>
#include<mutex>
class Server;
#include"Server.h"

// 会话类,继承自enable_shared_from_this以支持在回调函数中使用shared_ptr
class Session : public std::enable_shared_from_this<Session>
{
public:
    // 构造函数,初始化会话对象
    Session(boost::asio::io_context& ioc, Server* server);
    // 获取会话的socket对象引用
    boost::asio::ip::tcp::socket& getSocket();
    // 启动会话处理
    void start();
    // 发送消息
    void sendMess(boost::asio::const_buffer msg, std::shared_ptr<Session> self);
    // 处理发送操作完成后的回调
    void handleSend(const boost::system::error_code ec, std::size_t bytes_transferred, std::shared_ptr<Session> self);
    // 读取数据
    void read(boost::system::error_code ec, std::size_t bytes_transferred, std::shared_ptr<Session> self);
    // 析构函数
    ~Session();
private:
    // 会话的socket对象
    boost::asio::ip::tcp::socket sock;
    // 待发送消息队列
    std::queue<boost::asio::const_buffer> quebuf;
    // 读取数据的缓冲区
    char read_buffer[1024] = { 0 };
    // 缓冲区中数据长度
    int l = 0;
    // 发送操作互斥锁
    std::mutex send_mutex;
    // 关联的服务器对象指针
    Server* server;
};

Session.cpp

#include "Session.h"
#include<iostream>
Session::Session(boost::asio::io_context& ioc, Server* server):sock(ioc),server(server)
{
}

boost::asio::ip::tcp::socket& Session::getSocket()
{
	return sock;
}

void Session::start()
{
	sock.async_read_some(boost::asio::buffer(read_buffer, 1024), 
		std::bind(&Session::read, this, std::placeholders::_1, std::placeholders::_2,shared_from_this()));
}

void Session::sendMess(boost::asio::const_buffer msg, std::shared_ptr<Session> self)
{
	std::lock_guard<std::mutex> lock(send_mutex);
	if (!quebuf.empty())
	{
		quebuf.push(msg);
	}
	else
	{
		quebuf.push(msg);
		sock.async_send(quebuf.front(), std::bind(&Session::handleSend, this, std::placeholders::_1, std::placeholders::_2,self));
	}
}

void Session::handleSend(const boost::system::error_code ec, std::size_t bytes_transferred, std::shared_ptr<Session> self)
{
	if (ec)
	{
		std::cout << ec.value() << " - " << ec.message();
		server->stopSession(shared_from_this());
	}
	else
	{
		std::lock_guard<std::mutex> lock(send_mutex);
		quebuf.pop();
		if (!quebuf.empty())
		{
			sock.async_send(quebuf.front(), std::bind(&Session::handleSend, this, std::placeholders::_1, std::placeholders::_2,self));
		}
	}
}

void Session::read(boost::system::error_code ec, std::size_t bytes_transferred, std::shared_ptr<Session> self)
{
	if (ec)
	{
		std::cout << ec.value() << " = " << ec.message() << std::endl;
		server->stopSession(shared_from_this());
	}
	else
	{
		std::cout << read_buffer + l << std::endl;
		sendMess(boost::asio::buffer(read_buffer+l, bytes_transferred),self);
		l += bytes_transferred;
		sock.async_read_some(boost::asio::buffer(read_buffer + l, 1024 - l), std::bind(&Session::read, this, std::placeholders::_1, std::placeholders::_2,self));
	}
}

Session::~Session()
{
	std::cout << "Session closed" << std::endl;
}

Server.h

#pragma once
#include<boost/asio.hpp>
#include<set>
class Session;
#include"Session.h"
#include<memory>

class Server
{
public:
	// 构造函数,初始化 Server 对象
	Server(boost::asio::io_context& io_con, int port);
	// 开始接受连接请求
	void start();
	// 处理连接请求的回调函数
	void handle_accept(const boost::system::error_code ec, std::shared_ptr<Session> session_ptr);
	// 停止特定会话
	void stopSession(std::shared_ptr<Session> session_ptr);
private:
	boost::asio::io_context& _ioc;  // boost asio io 上下文的引用
	int port;  // 服务端口号
	boost::asio::ip::tcp::acceptor acc;  // 接受器对象
	std::set<std::shared_ptr<Session>> sessions;  // 会话集合
};

Server.cpp

#include"Server.h"
#include<iostream>
Server::Server(boost::asio::io_context& ioc, int port) :_ioc(ioc), port(port),acc(ioc,boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),port))
{

	start();
	ioc.run();

}

void Server::start()
{
	std::shared_ptr<Session> session_ptr = std::make_shared<Session>(_ioc,this);
	sessions.insert(session_ptr);

	acc.async_accept(session_ptr->getSocket(), std::bind(&Server::handle_accept,this, std::placeholders::_1, session_ptr ));
	
}

void Server::handle_accept( const boost::system::error_code ec, std::shared_ptr<Session> session_ptr )
{
	session_ptr->start();
	this->start();

}

void Server::stopSession(std::shared_ptr<Session> session_ptr)
{
	sessions.erase(session_ptr);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值