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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章