• c++异网正确使用接受


    原文

    正确使用受者

    异网受者有通过端点构造的重载函数,创建受者之后就可以接受了,代码如下:

    用 异网::ip::传控;
    传控::受者 受者(io环境,传控::端点(传控::v4(),端口));
    受者.异步接受(套接字,[](异网::错误码 ec){});
    
    
    • 1
    • 2
    • 3
    • 4

    该代码一般情况下没问题,但是如果端口被占用就会抛异常,需要注意捕获异常.
    如果不希望抛异常,则需要先监听端口再接受,如果监听失败就返回错误码.

    传控::受者 受者(io环境);
    受者.打开(端点.协议());
    受者.置选项(提升::异网::ip::传控::受者::重用地址());
    异网::错误码 ec;
    受者.绑定(端点,ec);(ec){
        输出<<"绑定端口失败"<<ec.消息()<<"\n";
        中 ec;
    }
    受者.();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这里面需要设置reuse_address选项,为什么要设置它?该选项对重启服务器有帮助,当套接字处于TIME_WAIT状态时,启动服务器,就会绑定失败,报已用地址错误,如果设置了reuse_address(true),则可以绑定成功.为什么第一个例子中不显式设置该参数呢,因为通过端点构造的受者默认参数就是reuse_addr=true.

    正确关闭受者

    写异步服务器时,需要通过异步循环调用异步接受:

    空 服务器::干接受()
    {
      受者_.异步接受(
          [](错误码 ec,异网::ip::传控::套接字 套接字)
          {(!ec)
            {
              连接管_.开始(造共<连接>(
                  移动(套接字),连接管_,请求处理器_));
            }{
                输出<<ec.消息()<<"\n";
            }
    
            干接受();
          });
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    需要注意错误处理,不像异步读写,它收到错误时不返回,而是继续接受,因为服务器在某一次接受失败时,还可继续接受其它连接,如果返回了,则整个服务器不能响应新连接了.上面代码错误处理还不够,关闭受者后,整个接受就会陷入死循环,一直会接受错误,所以正确处理错误方法是接受之前判断是否已经关闭受者了.

    空 服务器::干接受()
    {
      受者_.异步接受(
          [](错误码 ec,异网::ip::传控::套接字 套接字)
          {(!受者_.是打开())
            {;
            }
            ...后面相同,.
    
          });
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    关闭受者

    空 关闭(){
        错误码 ec
        受者_.关闭(ec);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这样,是错误的.会引起不可预测后果,因为受者正在异步接受,这时在另外线程中去关闭它,多线程操作受者会导致未定义行为,表现为有时候异步_接受会返回错误,有时候则会挂起主线程,而不会返回错误.在异步回调模式下,该错误造成影响似乎不太大,但在协程环境下,会导致永远不会返回异步接受的协程,这时如果再重启服务端则会出现客户端连接成功,但永远超时.
    正确关闭受者的方法是避免多线程去操作受者,通过提交去关闭它.

    空 关闭(){
        异网::提交(受者_.取执行器(),[]{
            错误码 ec
            受者_.关闭(ec);
        });
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    提交受者io环境里,可保证在同一线程里操作受者,确保正确关闭它.

  • 相关阅读:
    制作一个简单HTML校园网页(HTML+CSS)学校网站制作 校园网站设计与实现
    shell 内置命令
    Leetcode-141环形链表
    java 企业工程管理系统软件源码 自主研发 工程行业适用
    【知识点】怎么确定时间复杂度与空间复杂度
    嵌入式分享合集80
    【PTA-训练day4】L2-015 互评成绩 + L1-011 A-B
    利用互斥锁实现多个线程写一个文件
    使用Jenkins自动化部署项目
    五金机电行业智能供应链管理系统解决方案:数智化供应链为传统产业“造新血”
  • 原文地址:https://blog.csdn.net/fqbqrr/article/details/126461277