Boost asio入门学习笔记

Timer1:使用一个同步计时器

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


int main()
{
	boost::asio::io_context io;
	boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));
	t.wait();
	std::cout << "Hello,world!" << std::endl;
	
	return 0;
}

所谓的同步,就是指t.wait必须等待五秒才会向下执行。 

 

Timer2:使用一个异步计时器

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


void print(const boost::system::error_code&)
{
	std::cout << "Hello world!" << std::endl;
}
int main()
{
	boost::asio::io_context io;
	boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));
	t.async_wait(&print);
	std::cout << "Hehe!" << std::endl;
	io.run();
	return 0;
}

异步是指:上述程序并不会在t.async_wait(&print)处阻塞,而是继续运行,等到计时器计满5秒,才会调用print。上述程序的运行结果就是,先输出Hehe,再输出Hello world!。

Timer3:为handle绑定参数

#include <iostream>
#include "boost/asio.hpp"
#include "boost/bind.hpp"


void print(const boost::system::error_code&,boost::asio::steady_timer *t,int *count)
{
	if (*count < 5)
	{
		std::cout << *count << std::endl;
		++(*count);
		t->expires_at(t->expiry() + boost::asio::chrono::seconds(1));//设置新的过期时间
		t->async_wait(boost::bind(print, boost::asio::placeholders::error, t, count));//为print邦定参数,转换为函数对象
	}
}
int main()
{
	boost::asio::io_context io;
	int count = 0;
	boost::asio::steady_timer t(io, boost::asio::chrono::seconds(1));
	t.async_wait(boost::bind(print,boost::asio::placeholders::error,&t,&count));
	io.run();
	std::cout << "Final count is " << count << std::endl;
	return 0;
}

Timer4:使用一个成员函数作为handler

#include <iostream>
#include "boost/asio.hpp"
#include "boost/bind.hpp"


class printer
{
public:
	printer(boost::asio::io_context& io)
		:timer_(io, boost::asio::chrono::seconds(1)),
		count_(0)
	{
		timer_.async_wait(boost::bind(&printer::print, this));
	}
	~printer()
	{
		std::cout << "Final count is " << count_ << std::endl;
	}

	void print()
	{
		if (count_ < 5)
		{
			std::cout << count_ << std::endl;
			++count_;

			timer_.expires_at(timer_.expiry() + boost::asio::chrono::seconds(1));
			timer_.async_wait(boost::bind(&printer::print, this));
		}

	}
private:
	boost::asio::steady_timer timer_;
	int count_;
};
int main()
{
	boost::asio::io_context io;
	printer p(io);
	io.run();
	
	return 0;
}

与之前实例实现的功能一致,只不过更巧妙一些。the asio library provides a guarantee that callback handlers will only be called from threads that are currently calling io_context::run(). Consequently, calling io_context::run() from only one thread ensures that callback handlers cannot run concurrently.即,回调函数只能被一个线程调用,不能并行。

单线程有以下局限:

  • 如果handle非常耗时,将会造成可怜的响应速度。
  • 不能针对多核处理器进行扩展优化。

Timer5:多线程的同步Handlers

#include <iostream>
#include "boost/asio.hpp"
#include "boost/thread/thread.hpp"
#include "boost/bind.hpp"


class printer
{
public:
	printer(boost::asio::io_context& io)
		:strand_(io),
		timer1_(io, boost::asio::chrono::seconds(1)),
		timer2_(io,boost::asio::chrono::seconds(1)),
		count_(0)
	{
		timer1_.async_wait(boost::asio::bind_executor(strand_, boost::bind(&printer::print1, this))); //邦定在同一个strand对象上的handler不能并发
		timer2_.async_wait(boost::asio::bind_executor(strand_, boost::bind(&printer::print2, this)));

	}
	~printer()
	{
		std::cout << "Final count is " << count_ << std::endl;
	}

	void print1()
	{
		if(count_ < 10)
		{
			std::cout << "Timer 1: " << count_ << std::endl;
			++count_;

			timer1_.expires_at(timer1_.expiry() + boost::asio::chrono::seconds(1));

			timer1_.async_wait(boost::asio::bind_executor(strand_,
				boost::bind(&printer::print1, this)));
		}

	}

	void print2()
	{
		if (count_ < 10)
		{
			std::cout << "Timer 2: " << count_ << std::endl;
			++count_;

			timer2_.expires_at(timer2_.expiry() + boost::asio::chrono::seconds(1));

			timer2_.async_wait(boost::asio::bind_executor(strand_,
				boost::bind(&printer::print2, this)));
		}
	}

private:
	boost::asio::io_context::strand strand_;
	boost::asio::steady_timer timer1_;
	boost::asio::steady_timer timer2_;
	int count_;
};
int main()
{
	boost::asio::io_context io;
	printer p(io);
	boost::thread t(boost::bind(&boost::asio::io_context::run, &io));
	io.run();
	t.join();//等待子线程运行完毕
	
	
	return 0;
}

daytime1:实现一个同步的TCP daytime客户端

#include <iostream>
#include<boost/array.hpp>
#include "boost/asio.hpp"

using  boost::asio::ip::tcp;

int main(int argc,char * argv[])
{
	try
	{
		
		boost::asio::io_context io_context; //All programs that use asio need to have at least one io_context object.
		tcp::resolver resolver(io_context);

		std::string host = "127.0.0.1";//specify the host
										   //resolver需要一个query对象,并将query转换为a list of endpoints
										   //host name,也就是IP地址
										   //the name of service,也就是端口...
		tcp::resolver::query query(tcp::v4(), host, "13");
		//  tcp::resolver::query query(tcp::v4(),argv[1], "13");

		
		tcp::resolver::results_type endpoints = resolver.resolve(query);

		tcp::socket socket(io_context);
		boost::asio::connect(socket, endpoints);

		for (;;)
		{
			boost::array<char, 128>buf;
			boost::system::error_code error;

			size_t len = socket.read_some(boost::asio::buffer(buf), error);

			if (error == boost::asio::error::eof)
			{
				break;//连接关闭
			}
			else if (error)
			{
				throw boost::system::system_error(error);
			}

			std::cout.write(buf.data(), len);
		}
	}
	catch (const std::exception& e)
	{
		std::cerr << e.what() << std::endl;
	}
	
	return 0;
}

daytime2:实现一个同步的TCP daytime 服务端

#include <ctime>
#include <iostream>
#include <string>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

std::string make_daytime_string()
{
	using namespace std;
	time_t now = time(0);
	return ctime(&now);
}


int main()
{
	try
	{
		boost::asio::io_context io_context;
		tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 13));

		for (;;)
		{
			tcp::socket socket(io_context);
			acceptor.accept(socket);
			std::string message = make_daytime_string();
			boost::system::error_code igored_error;
			boost::asio::write(socket, boost::asio::buffer(message), igored_error);
		}
	}
	catch (const std::exception& e)
	{
		std::cerr << e.what() << std::endl;
	}
}

daytime3:一个异步tcp daytime的服务端

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

using boost::asio::ip::tcp;

std::string make_daytime_string()
{
	using namespace std;
	time_t now = time(0);
	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(boost::asio::io_context&io_context)
	{
		return pointer(new tcp_connection(io_context));
	}

	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(boost::asio::io_context&io_context)
		:socket_(io_context)
	{

	}
	void handle_write(const boost::system::error_code, size_t)
	{

	}
	tcp::socket socket_;
	std::string message_;
};


class tcp_server
{
public:
	tcp_server(boost::asio::io_context&io_context)
		:acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
	{
		start_accept();
	}

private:

	void start_accept()
	{
		tcp_connection::pointer new_connection = tcp_connection::create(acceptor_.get_executor().context());
		acceptor_.async_accept(new_connection->socket(), boost::bind(&tcp_server::handle_accept, this, new_connection, boost::asio::placeholders::error));

		//此处不阻塞,直接返回,当有连接到达时,调用handle_accept
	}

	void handle_accept(tcp_connection::pointer new_connection,
		const boost::system::error_code& error)
	{
		if (!error)
		{
			new_connection->start();
		}

		start_accept();
	}
	tcp::acceptor acceptor_;
};

int main()
{
	try
	{
		boost::asio::io_context io_context;
		tcp_server server(io_context);
		io_context.run();
	}
	catch (const std::exception& e)
	{
		std::cerr << e.what() << std::endl;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值