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