asio的使用

独立asio官网:https://think-async.com/Asio/index.html
asio中文文档:asio中文文档

1、下载

性能测试:https://github.com/huyuguang/asio_benchmark

2、基本使用

C/C++ 网络库 boost asio 使用详解
C++ 网络编程 asio 使用总结

2.1 TCP

1、客户端:
2、服务端:

2.2 UDP单播

boost的asio接收单路大数据量udp包的方法
1、发送:
同步:
udp客户端的socket 也有点不一样,它需要调用open函数,使用ipv4协议
然后其它的都一样,就是调用send_to与receive_from函数接受与发送数据即可

#include<iostream>
#include"boost/asio.hpp"
using namespace std;
using namespace boost;
using boost::asio::ip::udp;

int main() {
	asio::io_context io;
	udp::socket sock(io);
	sock.open(asio::ip::udp::v4());
	udp::endpoint serPoint(asio::ip::address::from_string("127.0.0.1"),6688);

	while (1) {
		char buf[0xFF];
		cin >> buf;
		sock.send_to(asio::buffer(buf), serPoint);
		memset(buf, 0, 0xFF);
		sock.receive_from(asio::buffer(buf), serPoint);
		cout << buf << endl;
	}
	::system("pause");
}

异步:

#include<iostream>
#include"boost/asio.hpp"
#include"boost/bind.hpp"
using namespace std;
using namespace boost;
using asio::ip::udp;

void sock_recv(char* buf, udp::socket* sock, udp::endpoint* cliPoint);
void sock_send(char* buf, udp::socket* sock, udp::endpoint* cliPoint);


int main() {
	cout << "server start ……" << endl;
	asio::io_context io;
	
	udp::socket *sock=new udp::socket(io, udp::endpoint(udp::v4(), 6688));

	char *buf=new char[0xFF];
	udp::endpoint *cliPoint=new udp::endpoint;

	sock->async_receive_from(asio::buffer(buf,0xFF),*cliPoint,boost::bind(sock_recv,buf,sock,cliPoint));

	io.run();

}


void sock_send(char* buf, udp::socket* sock, udp::endpoint* cliPoint) {
	try
	{
		sock->async_receive_from(asio::buffer(buf, 0xFF), *cliPoint, boost::bind(sock_recv, buf, sock, cliPoint));
	}
	catch (const std::exception& e)
	{
		cout << e.what();
	}
	
}

void sock_recv(char* buf, udp::socket* sock, udp::endpoint* cliPoint) {
	try
	{
		sock->async_send_to(asio::buffer(buf, 0xFF), *cliPoint, boost::bind(sock_send, buf, sock, cliPoint));

	}
	catch (const std::exception& e)
	{
		cout << e.what();
	}
}

2、接收:

#include "CircledBuffer.h"  
#include <iostream>  
#include <boost/asio.hpp>  
#include <boost/bind.hpp> 

using boost::asio::ip::udp;  
boost::asio::io_service service;  
boost::asio::ip::udp::socket sock(service);  
boost::asio::ip::udp::endpoint sender_ep;  
CircledBuffer readBuffer;  
PacketBuffer* packet;  

int main(int argc, char* argv[]) {  
    boost::asio::ip::udp::endpoint ep( boost::asio::ip::address::from_string("192.168.1.206"),  
        9002);  
    sock.open(ep.protocol());  
    sock.set_option(boost::asio::ip::udp::socket::reuse_address(true));  
    boost::asio::socket_base::receive_buffer_size recv_option(8*65534);  
    sock.set_option(recv_option);  
    sock.bind(ep);  
    packet = readBuffer.GetLast();  
    sock.async_receive_from(boost::asio::buffer(packet->data, packet->bufferSize), sender_ep, &on_read);  
    service.run();  
}  


void on_read(const boost::system::error_code & err, std::size_t  read_bytes) 
{  
     std::cout << "read: " << read_bytes << std::endl;  
     readBuffer.MoveNext();  
     packet= readBuffer.GetLast();  
     sock.async_receive_from(boost::asio::buffer(packet->data, packet->bufferSize), sender_ep, &on_read);  
}  

2.3 udp组播

1、发送:
2、接收:

2.4 多线程

asio模型(io_context 和 thread的使用)
boost asio的work作用
用io_service构造出一个work之后,再执行io_service_.run();就是阻塞的了。但是主线程不可以阻塞,否则后面的代码没法执行了。work: 可以防止io_service里注册的所有事件完成时退出事件循环。

boost::asio::io_service io_service_;
boost::asio::io_service::work work_(io_service_);
boost::thread th(run_io);
void run_io()
{
    io_service_.run();
}

新版 ASIO 必须以 asio::io_context 替换 asio::io_service

#include <iostream>
#include <thread>
#include <boost/asio.hpp>
#include <chrono>
 
std::string raw_ip_addr = "127.0.0.1";
unsigned short port_num = 6768;
 
int main() {
    boost::asio::io_context ioc;
    boost::asio::ip::tcp::endpoint
    ep(boost::asio::ip::address::from_string(raw_ip_addr), port_num);
    boost::asio::ip::tcp::socket sock(ioc, ep.protocol());
    boost::asio::ip::tcp::socket sock1(ioc, ep.protocol());
    boost::asio::ip::tcp::socket sock2(ioc, ep.protocol());
 
    boost::asio::io_context::work worker(ioc);
    std::thread t([&ioc](){ioc.run();});
 
    std::cout << "Main thread will for 1 seconds...\n";
    std::this_thread::sleep_for(std::chrono::seconds(1));  // 这里是防止回调启动过快
    std::cout << "Main thread weak up...\n";
 
    sock.async_connect(ep, [](const boost::system::error_code & err) {
        if (err.value() != 0) {
            std::cout << err.message() << std::endl;
        }
    });
 
    sock1.async_connect(ep, [](const boost::system::error_code & err) {
        if (err.value() != 0) {
            std::cout << err.message() << std::endl;
        }
    });
 
    sock2.async_connect(ep, [](const boost::system::error_code & err) {
        if (err.value() != 0) {
            std::cout << err.message() << std::endl;
        }
    });
 
    std::cout << "Main thread will for 1 seconds...\n";  // 这里是为了放置stop()执行过快
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Main thread weak up...\n";
    ioc.stop();  // 先显式停止io_context, 否则无法终止
    t.join();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值