首页 > 其他分享 >single_set

single_set

时间:2024-11-01 20:01:52浏览次数:3  
标签:set service int ip ec single io error

信号

信号是UNIX系统里常用的进程间异步通信方式
asio库提供类,利用异步IO的方式处理UNIX信号
类原型

class signal_set{
public:
    explicit signal_set(io_service& io_service);
    signal_set(io_service& io_serv, int number, ...);

    void add(int signal_number);
    void remove(int signal_number);
    void clear();

    void cancel();
    void async_wait(SignalHandler handler);
};

构造函数中传入io_service以提供异步操作
cancel()取消所有handler的执行,实际上是向它们传入boost::asio::error::operation_aborted错误,要求handler执行自己的cancel逻辑
async_wait()异步添加信号处理函数,即handler,是非阻塞的,无需等待即可返回,handler形式如下:

void handler(const system::error_code& ec, int signal_number);

示例

io_service io;
signal_set sig(io, SIGINT, SIGUSR1);
// sig.add(SIGINT);
// sig.add(SIGUSR1);

auto handler1=[](const error_code& ec, int n){
    if(ec){
        cout<<ec.message()<<endl;
        return;
    }
    if(n!=SIGINT){
        return;
    }
    cout<<"handler1 recv="<<n<<endl;
    cout<<"do something"<<endl;
};

typedef void(handler_type)(const error_code&,int);

function<handler_type> handler2=[](const error_type& ec, int n){
    if(n!=SIGUSR1){
        return;
    }
    cout<<"handler2 recv="<<n<<endl;
};

sig.async_wait(handler1);
sig.async_wait(handler2);

io.run(); // 启动事件循环,阻塞等待信号事件
cout<<"io stopped"<<endl;

执行命令kill -10 pid将会发送信号SIGUSR1,运行结果如下:

handler2 recv=10
io stopped

事件发生后,执行了对应的handler2,由于信号发生后注册的异步事件已经完成,所以io_service会结束事件循环,退出run()
若想持续捕获信号,需要在信号处理完重新添加

function<handler_type> handler2=[](const error_type& ec, int n){
    // ...
    sig.async_wait(handler1);
    sig.async_wait(handler2);
};

启用跟踪日志

#define BOOST_ASIO_ENABLE_HANDLER_TRACKING
#include<boost/asio.hpp>

将输出重定向到日志文件

signal_set 2 > out.log

其他

超时处理

steady_timer t(io, 500ms)
t.async_wait(
    [&](const error_code&){}
);

流处理

服务端

io_service io;
ip::tcp::endpoint ep(ip::tcp::v4(), 6688);
ip::tcp::acceptor acceptor(io, ep);
for(;;){
    ip::tcp::iostream tcp_stream;
    acceptor.accept(*tcp_stream.rdbuf());
    tcp_stream<<"hello tcp stream";
}

客户端

for(int i=0; i<5; ++i){
    ip::tcp::iostream tcp_stream("127.0.0.1", "6688")
    string str;
    getline(tcp_stream, str);
    cout<< str <<endl;
}

UDP协议通信

UDP是无连接的,使用send_to()receive_from()可以直接通过端点发送数据
服务端

int main(){
    io_service io;
    ip::udp::socket sock(io, ip::udp::endpoint(ip::udp::v4(),6699));
    while(true){
        char buf[1];
        ip::udp::endpoint ep;
        error_code ec;
        // 阻塞等待远程连接,端点信息存在ip对象中
        sock.receive_from(buffer(buf), ip, 0, ec);
        if(ec && ec!=message_size){
            throw system_error(ec);
            cout<<"send to:"<<ep.address()<<endl;
            sock.send_to(buffer("hello asio udp"), ep);
        }
    }
}

客户端

int main(){
    io_service io;
    ip::udp::endpoint send_ep(ip::address::from_string("127.0.0.1"),6699);

    ip::udp::socket sock(io);
    sock.open(ip::udp::v4());
    char buf[1];
    sock.send_to(buffer(buf), send_ep);

    vector<char> v(100,0);
    ip::udp::endpoint recv_ep;
    sock.receive_from(buffer(v), recv_ep);
    cout<<"recv from:"<<recv_ep.address()<<' ';
    cout<<&v[0]<<endl;
}

UNIX描述符

除了网络通信,asio还支持UNIX Domain Socket和文件描述符操作
可以使用async_read_some()/async_write_some()等函数执行异步读写操作

io_service io;
typedefboost::asio::posix::stream_descriptor descriptor_type;
descriptor_type in(io, STDIN_FILENO);
vector<char> buf(30);

typedef void(handler_type)(const error_code&, std::size_t);

function<handler_type> handler=[&](const error_code& ec, std::size_t len){
    if(ec){ return; }
    if(len < buf.size()){
        buf[len]= 0;
    }
    cout<<buf.data();
    in.async_read_some(buffer(buf), handler);
};
in.async_read_some(buffer(buf), handler);
io.run();

UNIX文件描述符也可以使用协程

io_service io;
typedef boost::asio::posix::stream_descriptor descriptor_type;
descriptor_type in(io, STDIN_FILENO);
vector<char> buf[30];

// 产生协程
spawn(
    io,
    [&](yield_context yield){
        while(true){
            error_code ec;
            auto len= in.async_read_some(buffer(buf), yield[ec])
            if(ec){ return; }
            if(len<buf.size()){
                buf[len]= 0;
            }
            cout<<buf.data();
        }
    }
):
io.run();

标签:set,service,int,ip,ec,single,io,error
From: https://www.cnblogs.com/sgqmax/p/18521155

相关文章

  • KingbaseES V8R6集群备份恢复案例之---主库single-pro备份恢复
    案例说明:KingbaseESV8R6集群物理备份支持single-pro方式,本案例在集群执行single-pro方式备份并多次切换集群后,对集群执行了恢复测试,文档记录了恢复的详细过程。适用版本:KingbaseESV8R6集群架构:ID|Name|Role|Status|Upstream|repmgrd|PID|Paused?|......
  • java.sql.SQLException: ORA-00971: 缺失 SET 关键字
    目录背景:过程:错误原因: 解决办法:总结:背景:正在运行某个项目程序,提交信息之后发现库中并没有刚刚的相关数据,后来查看后台信息,发现提示错误,java.sql.SQLException:ORA-00971:缺失SET关键字,下面一片红色,经过筛选,我看到(UserManage.java:194),显然是UserManage类里面的......
  • GEE 高阶应用:下载全球任何国家的森林损失保存到assets中
    目录简介数据函数filterMetadata(name, operator, value)Arguments:Returns: Collectionaggregate_array(property)Arguments:Returns: Listee.Number.parse(input, radix)Arguments:Returns: NumberclipToCollection(collection)Arguments:Returns: Ima......
  • windows 命令行执行.bat ,显示已经达到最大的setlocal递归层,解决办法
    windows命令行执行.bat,显示已经达到最大的setlocal递归层,网上也没有一个确切的解决办法,自己摸索寻找解决如下:C:\Users\yangz\Desktop>pingwww.baidu.com已经达到最大的setlocal递归层。一.解决思路:这条信息表明你在使用Windows命令提示符(CMD)时遇到了一个错误。错误信......
  • 用哈希表封装myunordered_map和myunordered_set
    在学习这个之前,已经学习过,myunordered_map和myunordered_set的基本用法和哈希表怎么用哈希思想模拟实现;因此为了更深入的了解myunordered_map和myunordered_set与哈希表的内容,我们来自己用哈希表模拟实现myunordered_map和myunordered_set;这种模拟实现和之前模拟实现map与set......
  • Windows11系统iisetw.dll文件丢失问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个iisetw.dll文件(挑选合适的版本文件)把它放......
  • 选择使用通用视图(Generic Views)或视图集(ViewSets)
    在DjangoRESTFramework中,通用视图和视图集都可以用于快速构建RESTAPI。它们各自有不同的适用场景,下面将详细介绍如何在两者之间进行选择。通用视图(GenericViews)通用视图提供了一些常用的、独立的视图类,如ListCreateAPIView、RetrieveUpdateDestroyAPIView等,用于处理增删改......
  • rust中map和set的基本使用
    1.HahsMaphttps://rustwiki.org/zh-CN/std/collections/struct.HashMap.html跟着文档,查看一下hashmap的方法,调试,输出一下,就能学会使用了。usestd::collections::HashMap;usestd::any::type_name;//输出变量类型fnprint_type_of<T>(_:&T){println!("{}",type_name......
  • OpenVINO(set_input_tensor())
    目录1.函数概述2.函数定义3.常见用法4.注意事项5.其他方法对比在OpenVINO中,set_input_tensor()函数用于将输入数据(即图像或其他类型的数据张量)传递给模型的输入端口。在使用OpenVINO进行推理时,需要将数据以正确的格式加载到模型的输入中,这样模型才能对数据进行处理。set_i......
  • Array and string offset access syntax with curly braces is deprecated
    你遇到的这个问题确实是因为PHP版本升级后对一些语法的支持发生了变化。具体来说,从PHP7.4开始,使用大括号 {} 访问数组和字符串的偏移已经被弃用,并将在未来的版本中完全移除。因此,你需要对代码进行相应的调整。解决方法方法一:降级PHP版本更改PHP版本为7.0以下的版本:如果你......