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;
}