【Boost】boost库asio详解8——几个TCP的简单例子

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

你可能感兴趣的:(【Boost】boost库asio详解8——几个TCP的简单例子)