asio学习之 UDP服务器

想找一个好的c++网络库,选来选去都不太满意,

mudo不支持windows,也不支持UDP,

evpp 有点复杂,

libevent是C语言的,

最后感觉还是asio最完善,支持最好,据说c++20标准中可能标准化,所以就进行一些学习。

1.基本使用

需要定义 ASIO_STANDALONE   单独使用asio不使用boost的。

windows平台下要定义 _WIN32_WINNT,具体可参见https://blog.csdn.net/caoshangpa/article/details/52807929

2.udp server 的基本例子,源码从asio的examples/cpp03/echo/async_udp_echo_server.cpp中取出,进行了一点小改动

主要是我用的是vs2015,有c++11,原来的代码依赖于boost。

记录如下:

1.同步版



#define ASIO_STANDALONE	
#define D_WIN32_WINNT  0x0501



#include <string>
#include <asio.hpp>
using namespace std;
using namespace asio;



int main(int argc, char* argv[])
{

	io_service my_io_service;

	ip::udp::endpoint local_endpoint(ip::address_v4::from_string("127.0.0.1"), 2300);//create  a local endpoint

	ip::udp::endpoint romote_endpoint; //this enpoint is used to store the endponit from remote-computer

	ip::udp::socket socket(my_io_service, local_endpoint);//create socket and bind the endpoint

	char buffer[40000];

	int nAdd = 0;

	while (1)
	{
		memset(buffer, 0, 40000);//to initialize variables
		nAdd++;
		socket.receive_from(asio::buffer(buffer, 40000), romote_endpoint);//receive data from  remote-computer
		printf("recv %d datapacket:%s\n", nAdd, buffer);
	}
	return 0;
}

 

2.异步版


#define ASIO_STANDALONE	
#define _WIN32_WINNT  0x0601 



#include <cstdlib>
#include <iostream>


#include "asio.hpp"

using asio::ip::udp;
using namespace std;

class server
{
public:
	server(asio::io_context& io_context, short port)
		: socket_(io_context, udp::endpoint(udp::v4(), port))
	{
		socket_.async_receive_from(
			asio::buffer(data_, max_length), sender_endpoint_,
			bind(&server::handle_receive_from, this,
				placeholders::_1,
				placeholders::_2));
	}

	void handle_receive_from(const asio::error_code& error,
		size_t bytes_recvd)
	{
		if (!error && bytes_recvd > 0) 
		{
			printf("received:%d, content:[%s]\n", bytes_recvd, data_);

			socket_.async_send_to(
				asio::buffer(data_, bytes_recvd), sender_endpoint_,
				bind(&server::handle_send_to, this,
					placeholders::_1,
					placeholders::_2));
		}
		else
		{
			socket_.async_receive_from(
				asio::buffer(data_, max_length), sender_endpoint_,// this->handle_receive_from);
				bind(&server::handle_receive_from, this,
					placeholders::_1,
					placeholders::_2));
		}
	}

	void handle_send_to(const asio::error_code& /*error*/,
		size_t /*bytes_sent*/)
	{
		socket_.async_receive_from(
			asio::buffer(data_, max_length), sender_endpoint_,
			bind(&server::handle_receive_from, this,
				placeholders::_1,
				placeholders::_2));
	}

private:
	udp::socket socket_;
	udp::endpoint sender_endpoint_;
	enum { max_length = 1024 };
	char data_[max_length];
};

int main(int argc, char* argv[])
{
	try
	{
		if (argc > 2)
		{
			std::cerr << "Usage: async_udp_echo_server <port>\n";
			return 1;
		}

		asio::io_context io_context;

		using namespace std; // For atoi.
		server s(io_context, atoi("2300"));

		io_context.run();
	}
	catch (std::exception& e)
	{
		std::cerr << "Exception: " << e.what() << "\n";
	}

	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

路边闲人2

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

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

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

打赏作者

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

抵扣说明:

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

余额充值