如何使用asio封装的异步处理udp数据的服务类?
平时工作中会经常用到UDP收发数据,下面分享一个常用的基于asio接口的简单封装;
asio是一个boost库中的一个组件,也可以单独引用该库,主要用于网络编程,具体大家可以百度详细说明。
这篇文章,主要分享一种简单应用,启动一个UDP服务,接收对端数据,并且可以返回数据;
代码如下(示例):
/*usdsocket.h*/
#ifndef _UDPSOCKET_H
#define _UDPSOCKET_H
#include
#include "boost/asio.hpp"
#include "boost/thread.hpp"
using namespace std;
using namespace boost::asio;
using namespace boost::asio::ip;
namespace BW_UDPRecv
{
/*data call back*/
typedef void (CALLBACK* LPDEAL_UDP)(unsigned char*data, int length, string & ip, int port);
typedef udp::socket udp_socket_t;
typedef std::function<void(const std::error_code, size_t)> OnSent;
class CRtpUdpServer :public std::enable_shared_from_this<CRtpUdpServer>
{
protected:
std::shared_ptr< udp_socket_t> m_socket;
udp::endpoint m_peer;
unsigned char m_sendBuf[1024];
unsigned char m_recvBuf[1024];
bool m_bindSucceed;
bool m_run;
protected:
void do_recv();
void send_data_to(void *buf, uint32_t len, const udp::endpoint &to, const OnSent &onSent);
int run();
public:
//CRtpUdpServer();
CRtpUdpServer(const string & ip, uint32_t port);
virtual ~CRtpUdpServer();
void start(LPDEAL_UDP lp);
void close();
void SendData(const char*data, int len);
bool getbindsucceed();
bool isRun();
void runThread();
private:
LPDEAL_UDP m_lpdata;
io_service m_ioserv;
};
}
#endif
/*udpsocket.cpp*/
#include "UdpSocket.h"
namespace BW_UDPRecv
{
void CRtpUdpServer::do_recv()
{
memset(m_recvBuf, 0, 1024);
auto buf = buffer(m_recvBuf, 1024);
m_socket->async_receive_from(buf, m_peer, [this](const std::error_code & ec, size_t len)
{
if (!ec)
{
if (m_lpdata != nullptr)
{
m_lpdata(m_recvBuf, len, m_peer.address().to_v4().to_string(), m_peer.port());
}
do_recv();
}
else
{
m_bindSucceed = false;
}
});
}
CRtpUdpServer::CRtpUdpServer(const string & ip, uint32_t port)
{
m_lpdata = NULL;
try
{
m_socket = std::make_shared<udp_socket_t>(m_ioserv, udp::endpoint(address::from_string(ip), port));
}
catch (...)
{
m_run = false;
return;
}
m_run = true;
}
CRtpUdpServer::~CRtpUdpServer() {
}
bool CRtpUdpServer::isRun()
{
return m_run;
}
void CRtpUdpServer::close()
{
if (m_run)
m_socket->close();
m_ioserv.stop();
}
void CRtpUdpServer::start(LPDEAL_UDP lp)
{
if (m_lpdata == nullptr)
m_lpdata = lp;
do_recv();
}
bool CRtpUdpServer::getbindsucceed()
{
return m_bindSucceed;
}
void CRtpUdpServer::send_data_to(void *buf, uint32_t len,
const udp::endpoint &to, const OnSent &onSent)
{
memcpy(m_sendBuf, buf, len);
m_socket->async_send_to(buffer(m_sendBuf, len), to, onSent);
}
void CRtpUdpServer::SendData(const char*data, int len)
{
send_data_to((void*)data, len, m_peer, [this](std::error_code ec, size_t len)
{
if (!ec)
{
//出现error
}
});
}
void CRtpUdpServer::runThread()
{
boost::thread thd(&CRtpUdpServer::run,this);
thd.timed_join(boost::posix_time::milliseconds(1));
}
int CRtpUdpServer::run()
{
m_ioserv.run();
return 0;
}
};
代码如下(示例):
void CALLBACK UdpdataCallback(unsigned char*data, int length, string&ip, int port)
{
//此处处理数据、、、、、、
}
std::shared_ptr<BW_UDPRecv::CRtpUdpServer> udpServer = std::make_shared<BW_UDPRecv::CRtpUdpServer>(string(ip), port);
if (udpServer->isRun() == false)
{
//绑定参数错误,发现异常
}
else
{
//传输数据回调接口
udpServer->start(UdpdataCallback);
udpServer->runThread();
//启动完成
}
分享一个基于boost.asio组件开发的网络库,实现了最基本的数据收发功能,欢迎有问题留言,共同进步。