C++实现简单的async回显服务器客户端(boost/asio)

async_server.cpp

#include <iostream>
#include <boost/asio.hpp>
#include <boost/noncopyable.hpp>
#include <string>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

using namespace boost::asio;
using namespace std;

enum
{
    max_mag = 1024
};

io_service service;                        // 它将创建一个 TCP 服务器
ip::tcp::endpoint ep(ip::tcp::v4(), 8001); // 监听端口 8001
ip::tcp::acceptor acceptor(service, ep);   // 创建一个 ip::tcp::acceptor 对象 acceptor 来监听端口 8001

class talk_to_client : public boost::enable_shared_from_this<talk_to_client>,
                       // 作用:boost::enable_shared_from_this 是用于在智能指针环境下安全地获取指向自身的智能指针
                       // 当一个类继承自 boost::enable_shared_from_this(或 std::enable_shared_from_this),
                       //  它就可以在成员函数中使用 shared_from_this() 方法来获取一个指向自身的 shared_ptr(或 std::shared_ptr)。
                       //  这样,就可以避免在智能指针环境下出现潜在的内存管理问题,例如在对象还存在其他共享指针时被删除。
                       boost::noncopyable
// 作用:boost::noncopyable 禁止了复制构造函数和赋值操作符,防止对象被复制和赋值。
// boost::noncopyable 是 Boost 库中的一个类,用于禁用类的复制构造函数和赋值操作符。
//  通过继承 boost::noncopyable,可以确保一个类对象不能被复制或赋值,从而避免不希望的对象拷贝和共享资源导致的问题。
//  talk_to_client() : sock(service), status(false) {}   避免外面对sock和status进行复制和赋值

{
    typedef talk_to_client self_type;

private:
    ip::tcp::socket sock;
    char read_buf[max_mag];
    char write_buf[max_mag];
    bool status;

public:
    typedef boost::shared_ptr<talk_to_client> ptr; // 定义了 ptr 类型为智能指针,用于管理 talk_to_client 类的对象。
    typedef boost::system::error_code error_code;  // 初始化 sock(TCP socket)、status(连接状态)

public:
    talk_to_client() : sock(service), status(false) {}

    static ptr creat_() // 静态工厂函数,创建一个指向 talk_to_client 对象的智能指针
    {
        ptr creat_(new talk_to_client);
        return creat_;
    }
    void star()
    {
        status = true;
        do_read();
    }
    ip::tcp::socket &sock_()
    {
        // 这个函数返回一个引用(&)到 ip::tcp::socket 对象,名为 sock。
        // 这样的函数允许外部代码访问 talk_to_client 类内部的私有成员变量 sock,而不是返回副本或指针,从而可以直接操作和使用这个成员变量。
        return sock;
    }
    void stop()
    {
        if (!status)
            return;
        status = false;
        sock.close();
    }
    void do_read()
    {
        async_read(sock, buffer(read_buf, max_mag), boost::bind(&self_type::on_read, shared_from_this(), _1, _2));
    }
    void on_read(const error_code &err, size_t bytes_transferred)
    {
        if (err)
            stop();
        do_write(bytes_transferred);
    }
    void do_write(size_t bytes_transferred)
    {
        strcpy(write_buf, read_buf);
        async_write(sock, buffer(write_buf, bytes_transferred), boost::bind(&self_type::on_write, shared_from_this(), _1, _2));
    }
    void on_write(const error_code &err, size_t bytes_transferred)
    {
        if (err)
            stop();
        do_read();
    }
};

void handle_accept(talk_to_client::ptr client, const boost::system::error_code &err)
{
    if (!err)
    {
        client->star();
        talk_to_client::ptr client = talk_to_client::creat_();                          // 创建一个 talk_to_client 对象的智能指针 client
        acceptor.async_accept(client->sock_(), boost::bind(handle_accept, client, _1)); // 传参时,需要与handle_accept里的参数保持一致,client就必须为里面的第一个参数
    }
}

int main(int argc, char const *argv[])
{

    talk_to_client::ptr client = talk_to_client::creat_();                          // 创建一个 talk_to_client 对象的智能指针 client
    acceptor.async_accept(client->sock_(), boost::bind(handle_accept, client, _1)); // 传参时,需要与handle_accept里的参数保持一致,client就必须为里面的第一个参数
    service.run();
    return 0;
}

async_client.cpp

#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/noncopyable.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>

#define BUFF_MAX_SIZE 1024

using namespace boost::asio;
using namespace boost::placeholders;

class client : public boost::enable_shared_from_this<client>, boost::noncopyable
{
private:
    ip::tcp::socket sock;
    ip::tcp::endpoint ep;
    char read_buf[BUFF_MAX_SIZE];
    char write_buf[BUFF_MAX_SIZE];

public:
    typedef boost::shared_ptr<client> ptr;
    typedef boost::system::error_code error_code;
    client(boost::asio::io_service &service, const char *addr, int port) : sock(service), ep(ip::address::from_string(addr), port){};

public:
    static ptr creat(boost::asio::io_service &service, const char *addr, int port)
    {
        return ptr(new client(service, addr, port));
    }

    void do_read(const error_code &err, size_t bytes)
    {
        if (err)
        {
            std::cout << "write is fail!" << std::endl;
            sock.close();
        }
        async_read(sock, buffer(read_buf, BUFF_MAX_SIZE), [&](const error_code &err, size_t bytes)
                   {
                    if (err)
                    {
                        sock.close();
                    }
                    
             fprintf(stdout,"%s",read_buf);
            do_write(); });
    }

    void do_write()
    {
        std::cout << "Please enter : " ;
        std::cin >> write_buf;
        async_write(sock, buffer(write_buf, BUFF_MAX_SIZE), boost::bind(&client::do_read, shared_from_this(), _1, _2));
    }

    void session_exec()
    {
        sock.async_connect(ep, boost::bind(&client::do_write, shared_from_this()));
    }
};

int main(int argc, char const *argv[])
{

    io_service service;

    client::ptr client_ = client::creat(service, "127.0.0.1", 8001);
    client_->session_exec();
    service.run();
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值