使用asio库封装的UDP收发数据类

如何使用asio封装的异步处理udp数据的服务类?

文章目录

  • 前言
  • 一、asio是什么?
  • 二、如何使用?
    • 1.废话不多说直接上代码
    • 2.调用示例
  • 总结


前言


平时工作中会经常用到UDP收发数据,下面分享一个常用的基于asio接口的简单封装;

一、asio是什么?

asio是一个boost库中的一个组件,也可以单独引用该库,主要用于网络编程,具体大家可以百度详细说明。
这篇文章,主要分享一种简单应用,启动一个UDP服务,接收对端数据,并且可以返回数据;

二、如何使用?

1.废话不多说直接上代码

代码如下(示例):

/*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;
	}
};

2.调用示例

代码如下(示例):

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组件开发的网络库,实现了最基本的数据收发功能,欢迎有问题留言,共同进步。

你可能感兴趣的:(提高工作效率,asio,udp,boost)