BOOST TCP 异步 网络通信

TCP服务端-异步 

①"TCPServerASYNC.h"

#ifndef TCPServerASYNC_h__
#define TCPServerASYNC_h__

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


// <summary> TCP服务端-异步; </summary>
//
//  在异步模式下,程序除了要发起IO操作,还要定义一个用于回调的完成处理函数;
//  io_service同样把IO操作转交给操作系统执行,但它不同步等待,而是立即返回;
//  调用io_service的run()成员函数可以等待异步操作完成,当异步操作完成时;
//  io_service从操作系统获取执行结果,调用完成处理函数;
//
// <remarks>    2017.6.8         </remarks>


typedef boost::shared_ptr<boost::asio::ip::tcp::socket> SockPtr;
class TCPServerASYNC
{
public:
	TCPServerASYNC( boost::asio::io_service &ios, boost::asio::ip::tcp::endpoint &endpoint );

	void Start(); //Start函数用于启动异步接受连接;
	void AcceptHandler( const boost::system::error_code & ec, SockPtr sockPtr ); //当有TCP连接发生时,AcceptHandler()函数将被调用,它使用socket对象发送数据;
	void WriteHandler( const boost::system::error_code & ec ); //发送数据,发送完毕调用此函数输出信息;

private:
	boost::asio::io_service &IOS;
	boost::asio::ip::tcp::endpoint &EndPoint;
	boost::asio::ip::tcp::acceptor Acceptor;
};

#endif // TCPServerASYNC_h__
②"TCPServerASYNC.cpp"

#include <iostream>

#include "TCPServerASYNC.h"

TCPServerASYNC::TCPServerASYNC( boost::asio::io_service &ios, boost::asio::ip::tcp::endpoint &endpoint )
	:IOS( ios )
	,EndPoint( endpoint )
	,Acceptor( IOS, EndPoint )
{
}

//Start函数用于启动异步接受连接,需要调用acceptor的async_accept()函数;
//为了能够让socket对象能够被异步调用后还能使用;
//我们必须使用shared_ptr来创建socket对象的智能指针;
//它可以在程序的整个生命周期中存在,直到没人使用它为止;
void TCPServerASYNC::Start()
{
	SockPtr sockPtr( new boost::asio::ip::tcp::socket(IOS) );

	//异步侦听服务,有连接请求后调用AcceptHandler函数;
	Acceptor.async_accept( *sockPtr, boost::bind( &TCPServerASYNC::AcceptHandler, this, boost::asio::placeholders::error, sockPtr ) );
}

//当有TCP连接发生时,AcceptHandler()函数将被调用,它使用socket对象发送数据;
void TCPServerASYNC::AcceptHandler( const boost::system::error_code & ec, SockPtr sockPtr )
{
	if ( ec ) //检测错误码;
	{
		return;
	}

	std::cout << "client : " << sockPtr->remote_endpoint().address() << std::endl;

	//发送数据,发送完毕后,调用WriteHandler()函数;
	sockPtr->async_write_some( boost::asio::buffer("Hello TCP"), boost::bind(&TCPServerASYNC::WriteHandler, this, boost::asio::placeholders::error) );
}

void TCPServerASYNC::WriteHandler( const boost::system::error_code & ec )
{
	if ( ec ) //检测错误码;
	{
		return;
	}

	std::cout << "Send MSG complete." << std::endl;
}

③自定义定时器 "LHCTimer.h"

#ifndef LHCTimer_h__
#define LHCTimer_h__

#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>


// <summary> 自定义计时器,该计时器在second秒后结束,结束后执行func函数,循环countMax次; </summary>
// <remarks>    2017.6.8         </remarks>

class LHCTimer
{
public:
	
	// <summary> 自定义计时器的模板构造函数; </summary>
	//
	//   second:计时器Timer结束时间;
	//   countMax:计时器Timer执行的次数;
	//   func:计时器结束后,所要执行的外部函数;
	// <remarks>    2017.6.8         </remarks>
	
	template<typename F>
	LHCTimer( boost::asio::io_service &ios, int second, int countMax, F func );

	//回调函数,调用次数为Count_Max,回调函数为Fun();
	void CallFunc( const boost::system::error_code & )
	{
		if ( Count > Count_Max )
		{
			return;
		}

		++Count;
		Fun();

		D_Timer.expires_at( D_Timer.expires_at() + boost::posix_time::seconds( Seconds ) );  //设置定时器的终止时间为Seconds秒;
		D_Timer.async_wait( boost::bind(&LHCTimer::CallFunc, this, boost::asio::placeholders::error) );  //异步等待计时器,注册回调函数;
	}

private:
	int Count; //计数用;
	int Count_Max; //计时器Timer执行的次数;
	int Seconds; //计时器Timer结束时间;

	boost::function<void()> Fun; //计时器结束后,所要执行的外部函数;
	boost::asio::deadline_timer D_Timer; //计时器变量;
};

template<typename F>  //模板类型,可以接受任意可调用物;
LHCTimer::LHCTimer( boost::asio::io_service &ios, int second, int countMax, F func )
	:Fun(func)
	,Seconds(second)
	,Count_Max(countMax)
	,D_Timer(ios, boost::posix_time::seconds(second)) //启动计时器;
{
	Count = 1;
	
	D_Timer.async_wait( boost::bind(&LHCTimer::CallFunc, this, boost::asio::placeholders::error) ); //异步等待计时器,注册回调函数;
}

#endif // LHCTimer_h__
④main.cpp
#include <iostream>

#include "LHCTimer.h"
#include "TCPServerASYNC.h"

int main( int argc, char * argv[] )
{
	//TCP服务器端-异步;
	// 在异步模式下,程序除了要发起IO操作,还要定义一个用于回调的完成处理函数;
	// io_service同样把IO操作转交给操作系统执行,但它不同步等待,而是立即返回;
	// 调用io_service的run()成员函数可以等待异步操作完成,当异步操作完成时;
	// io_service从操作系统获取执行结果,调用完成处理函数;
	{
		try
		{
			std::cout << "Server start." << std::endl;

			boost::asio::io_service ios;
			boost::asio::ip::tcp::endpoint endpoint( boost::asio::ip::tcp::v4(), 6688 );

			TCPServerASYNC server( ios, endpoint );

			//创建计时器,每隔2秒,执行TCPClient函数,执行5次;
			LHCTimer timer( ios, 2, 5, boost::bind(&TCPServerASYNC::Start, &server) );

			//调用io_service的run()成员函数可以等待异步操作完成;
			//当前run()用于等待LHCTimer计时器的异步操作,而非TCPClient绑定函数;
			ios.run();       //很重要,异步IO必须;她启动前摄器的时间处理循环,阻塞等待所有的操作完成并分派事件;
			                 //如果不调用run() 那么虽然操作被异步执行了,但没有一个等待它完成的机制,回调函数得不到执行机会;

		}
		catch ( boost::system::system_error &e )
		{
			std::cout << "process failed : " << e.what() << std::endl;
		}
	}

	system( "pause" );
	return 0;
}

TCP客户端-异步 

①"TCPClientASYNC.h"

#ifndef TCPClientASYNC_h__
#define TCPClientASYNC_h__

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


// <summary> TCP客户端-异步; </summary>
//
//  在异步模式下,程序除了要发起IO操作,还要定义一个用于回调的完成处理函数;
//  io_service同样把IO操作转交给操作系统执行,但它不同步等待,而是立即返回;
//  调用io_service的run()成员函数可以等待异步操作完成,当异步操作完成时;
//  io_service从操作系统获取执行结果,调用完成处理函数;
//
// <remarks>    2017.6.8         </remarks>


typedef boost::shared_ptr<boost::asio::ip::tcp::socket> SockPtr;
class TCPClientASYNC
{
public:
	TCPClientASYNC( boost::asio::io_service &ios, boost::asio::ip::tcp::endpoint &endpoint );

	void Start(); //Start函数用于启动异步接受连接;
	void ConnHandler( const boost::system::error_code & ec, SockPtr sockPtr ); //连接成功被调用,异步读取数据,并再启动一个异步连接;
	void ReadHandler( const boost::system::error_code & ec, boost::shared_ptr<std::vector<char>> str ); //异步读取结束时调用,输出信息;

private:
	boost::asio::io_service &IOS;
	boost::asio::ip::tcp::endpoint &EndPoint;

};

#endif // TCPClientASYNC_h__
②"TCPClientASYNC.cpp"
#include <iostream>

#include "TCPClientASYNC.h"

TCPClientASYNC::TCPClientASYNC( boost::asio::io_service &ios, boost::asio::ip::tcp::endpoint &endpoint )
	:IOS( ios )
	,EndPoint( endpoint )
{

}

void TCPClientASYNC::Start()
{
	SockPtr sock( new boost::asio::ip::tcp::socket(IOS) );

	//启动异步连接,连接成功后调用ConnHandler函数;
	sock->async_connect( EndPoint, boost::bind( &TCPClientASYNC::ConnHandler, this, boost::asio::placeholders::error, sock ) );
}

void TCPClientASYNC::ConnHandler( const boost::system::error_code & ec, SockPtr sockPtr )
{
	if ( ec ) //检测错误码;
	{
		return;
	}

	std::cout << "recive from " << sockPtr->remote_endpoint().address() << std::endl;

	//建立连接数据的缓冲区;
	boost::shared_ptr<std::vector<char>> str( new std::vector<char>(100, 0) );

	//异步读取数据,异步读取结束后,调用ReadHandler()函数;
	sockPtr->async_read_some( boost::asio::buffer(*str), boost::bind(&TCPClientASYNC::ReadHandler, this, boost::asio::placeholders::error, str) );
}

void TCPClientASYNC::ReadHandler( const boost::system::error_code & ec, boost::shared_ptr<std::vector<char>> str )
{
	if ( ec ) //检测错误码;
	{
		return;
	}

	std::cout << &(*str)[0] << std::endl;
}
③main.cpp

#include <boost/ref.hpp>

#include "LHCTimer.h"
#include "TCPClientASYNC.h"

int main( int argc, char * argv[] )
{	
	//TCP客户端-异步;
	// 在异步模式下,程序除了要发起IO操作,还要定义一个用于回调的完成处理函数;
	// io_service同样把IO操作转交给操作系统执行,但它不同步等待,而是立即返回;
	// 调用io_service的run()成员函数可以等待异步操作完成,当异步操作完成时;
	// io_service从操作系统获取执行结果,调用完成处理函数;
	{
		try
		{
			std::cout << "client start." << std::endl;

			boost::asio::io_service ios;
			boost::asio::ip::tcp::endpoint ep( boost::asio::ip::address::from_string("127.0.0.1"), 6688 );

			//创建TCP客户端对象;
			TCPClientASYNC server( ios, ep );


			//创建计时器,每隔2秒,执行TCPClient函数,执行5次;
			LHCTimer timer( ios, 2, 5, boost::bind(&TCPClientASYNC::Start, &server) );

			//调用io_service的run()成员函数可以等待异步操作完成;
			//当前run()用于等待LHCTimer计时器的异步操作,而非TCPClient绑定函数;
			ios.run();       //很重要,异步IO必须;她启动前摄器的时间处理循环,阻塞等待所有的操作完成并分派事件;
			                 //如果不调用run() 那么虽然操作被异步执行了,但没有一个等待它完成的机制,回调函数得不到执行机会;
		}
		catch ( boost::system::system_error &e )
		{
			std::cout << "process failed : " << e.what() << std::endl;
		}
	}

	system( "pause" );
	return 0;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值