您的位置:首页 > 理论基础 > 计算机网络

BOOST TCP 异步 网络通信

2017-08-11 14:29 169 查看
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>
///////////////////////////////////////
bbd5
/////////////////////////////////////////////////////////////
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐