摘于boost官网的几个例子, 做了点小修改, 笔记之.
同步客户端
void test_asio_synclient()
{
typedef boost::asio::io_service IoService;
// 该命名空间下有几个常用类: accetpt, resolver, endpoint, socket
typedef boost::asio::ip::tcp TCP;
try
{
IoService ios;
boost::system::error_code error;
// 1. 用解释器的方法, 常用来解析域名, 如
// query("www.163.com","80"), 也可以 query("www.163.com","telnet")
// echo 7/tcp
// ftp 21/tcp # File Transfer Protocol (Control)
// telnet 23/tcp # Virtual Terminal Protocol
// smtp 25/tcp # Simple Mail Transfer Protocol
// time 37/tcp timeserver # Time
// TCP::resolver resolver(ios);
// TCP::resolver::query query("127.0.0.1", "10000");
// TCP::resolver::iterator endpoint_iterator = resolver.resolve(query);
// TCP::resolver::iterator end;
// TCP::socket socket(ios);
// socket.connect(*endpoint_iterator, error);
// 2. 用简便的方法
TCP::socket socket(ios);
TCP::endpoint endpoint(boost::asio::ip::address_v4::from_string("127.0.0.1"), 10000);
socket.connect(endpoint, error);
// 这里要判断一下, 否则没有连上会通过.
if (error)
throw boost::system::system_error(error);
while(true)
{
// boost::array<char, 128> buf;
std::vector<char> buf(128);
size_t len = socket.read_some(boost::asio::buffer(buf), error);
// 这是也要判断一下, 否则服务端运行断开, 这里会出现死循环.
if (error == boost::asio::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw boost::system::system_error(error); // Some other error.
// buf要注意控制大小。
socket.write_some(boost::asio::buffer(buf, len), error);
}
}
catch (std::exception& e)
{
PRINT_DEBUG(e.what());
}
}
同步服务端
namespace
{
std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&now);
}
}
void test_asio_synserver()
{
typedef boost::asio::io_service IoService;
typedef boost::asio::ip::tcp TCP;
try
{
IoService ios;
/*
*以下构造函数相当于以下步骤
* basic_socket_acceptor<tcp> acceptor(io_service);
* acceptor.open(tcp::v4());
* acceptor.bind(tcp::endpoint(13));
* acceptor.listen(0);//default
*/
/*
tcp::endpoint(端点)由以下三个部分组成
1. IP地址(address, address_v4, address_v6)
2. 端口号
3. 协议版本
*/
TCP::acceptor acceptor(ios, TCP::endpoint(TCP::v4(), 13));
for (;;)
{
TCP::socket socket(ios);
acceptor.accept(socket);
std::string message = make_daytime_string();
boost::system::error_code ignored_error;
boost::asio::write(socket,
boost::asio::buffer(message),
boost::asio::transfer_all(),
ignored_error);
PRINT_DEBUG(message);
}
}
catch (std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
异步服务端
namespace
{
typedef boost::asio::io_service IoService;
typedef boost::asio::ip::tcp TCP;
std::string make_daytime_string()
{
using namespace std;
time_t now = std::time(NULL);
return ctime(&now);
}
class tcp_connection
: public boost::enable_shared_from_this<tcp_connection>
{
public:
typedef boost::shared_ptr<tcp_connection> pointer;
static pointer create(IoService& io_service)
{
return pointer(new tcp_connection(io_service));
}
TCP::socket& socket()
{
return socket_;
}
void start()
{
message_ = make_daytime_string();
boost::asio::async_write(
socket_,
boost::asio::buffer(message_),
boost::bind(&tcp_connection::handle_write,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
tcp_connection(IoService& io_service)
: socket_(io_service)
{
}
void handle_write(const boost::system::error_code& /*error*/,
size_t /*bytes_transferred*/)
{
PRINT_DEBUG("write data!!!");
}
TCP::socket socket_;
std::string message_;
};
class tcp_server
{
public:
tcp_server(IoService& io_service)
: acceptor_(io_service, TCP::endpoint(TCP::v4(), 10000))
{
start_accept();
}
private:
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.get_io_service());
acceptor_.async_accept(
new_connection->socket(),
boost::bind(&tcp_server::handle_accept,
this,
new_connection,
boost::asio::placeholders::error));
}
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code& error)
{
if (!error)
{
new_connection->start();
start_accept();
}
}
TCP::acceptor acceptor_;
};
}
// tcp_connection与tcp_server封装后
void test_asio_asynserver()
{
try
{
IoService io_service;
tcp_server server(io_service);
// 只有io_service类的run()方法运行之后回调对象才会被调用
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}