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

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


前言


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

一、asio是什么?

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

二、如何使用?

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

代码如下(示例):

/*usdsocket.h*/

#ifndef _UDPSOCKET_H
#define _UDPSOCKET_H

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

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShaYQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值