IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> boost::asio::ip::tcp::acceptor::async_accept 一直被死循环调用(无错误)问题的处理。 -> 正文阅读

[网络协议]boost::asio::ip::tcp::acceptor::async_accept 一直被死循环调用(无错误)问题的处理。

演示会发生异步死循环故障的代码实现:

        bool Socket::AcceptLoopbackAsync(
            const Hosting&                                          hosting,
            const boost::asio::ip::tcp::acceptor&                   acceptor,
            const BOOST_ASIO_MOVE_ARG(AcceptLoopbackCallback)       callback) noexcept {
            if (!acceptor.is_open()) {
                return false;
            }

            if (!hosting || !callback) {
                Closesocket(acceptor);
                return false;
            }

            const AsioContext context_ = hosting->GetContext();
            if (!context_) {
                Closesocket(acceptor);
                return false;
            }

            boost::asio::ip::tcp::acceptor* const acceptor_ = addressof(acceptor);
            const Hosting                         hosting_ = hosting;
            const AcceptLoopbackCallback          accept_ = BOOST_ASIO_MOVE_CAST(AcceptLoopbackCallback)(constantof(callback));
            const AsioTcpSocket                   socket_ = make_shared_object<boost::asio::ip::tcp::socket>(*context_);

            acceptor_->async_accept(*socket_,
                [hosting_, context_, acceptor_, accept_, socket_](const boost::system::error_code& ec) noexcept {
                    if (ec == boost::system::errc::operation_canceled) {
                        Closesocket(*acceptor_);
                        return;
                    }

                    bool success = false;
                    do { /* boost::system::errc::connection_aborted */
                        if (ec) { /* ECONNABORTED */
                            break;
                        }

                        int handle_ = socket_->native_handle();
                        Socket::AdjustDefaultSocketOptional(handle_, false);
                        Socket::SetTypeOfService(handle_);
                        Socket::SetSignalPipeline(handle_, false);
                        Socket::SetDontFragment(handle_, false);
                        Socket::ReuseSocketAddress(handle_, true);

                        /* Accept Socket?? */
                        success = accept_(context_, socket_);
                    } while (0);
                    if (!success) {
                        Closesocket(socket_);
                    }

                    success = AcceptLoopbackAsync(hosting_, *acceptor_, forward0f(accept_));
                    if (!success) {
                        Closesocket(*acceptor_);
                    }
                });
            return true;
        }

该问题发生的原因:

进程的最大文件描述符太小,当进程打开的文件描述符句柄(fd)数量超过,当前进程的 “Max open files”,那么会导致 accept 无法获取 session fd 而失败,但它并不产生错误,而此时 TCP/IP 连接的三次握手(或 FAST OPEN,单次)已建立连接。

而 boost::asio 采用 epoll LT(水平出发模式),该模式会导致,epoll 不停的触发 accept 事件到达,所以就产生了无限制的 async_accept 回调调用,故而又重新 async_accept,造成的死循环,即使没有实际的网络IO产生。

查看特定进程的 “Max open files” 值大小,人们可以使用以下的命令

cat /proc/进程PID/limits? ? ? ? ? ? ? ? ? ? ? ? ## 打印内容如下

Limit ? ? ? ? ? ? ? ? ? ? Soft Limit ? ? ? ? ? Hard Limit ? ? ? ? ? Units ? ??
Max cpu time ? ? ? ? ? ? ?unlimited ? ? ? ? ? ?unlimited ? ? ? ? ? ?seconds ??
Max file size ? ? ? ? ? ? unlimited ? ? ? ? ? ?unlimited ? ? ? ? ? ?bytes ? ??
Max data size ? ? ? ? ? ? unlimited ? ? ? ? ? ?unlimited ? ? ? ? ? ?bytes ? ??
Max stack size ? ? ? ? ? ?8388608 ? ? ? ? ? ? ?unlimited ? ? ? ? ? ?bytes ? ??
Max core file size ? ? ? ?0 ? ? ? ? ? ? ? ? ? ?unlimited ? ? ? ? ? ?bytes ? ??
Max resident set ? ? ? ? ?unlimited ? ? ? ? ? ?unlimited ? ? ? ? ? ?bytes ? ??
Max processes ? ? ? ? ? ? 1178 ? ? ? ? ? ? ? ? 1178 ? ? ? ? ? ? ? ? processes?
Max open files ? ? ? ? ? ?1000000 ? ? ? ? ? ? ?1000000 ? ? ? ? ? ? ?files ? ??
Max locked memory ? ? ? ? 67108864 ? ? ? ? ? ? 67108864 ? ? ? ? ? ? bytes ? ??
Max address space ? ? ? ? unlimited ? ? ? ? ? ?unlimited ? ? ? ? ? ?bytes ? ??
Max file locks ? ? ? ? ? ?unlimited ? ? ? ? ? ?unlimited ? ? ? ? ? ?locks ? ??
Max pending signals ? ? ? 1178 ? ? ? ? ? ? ? ? 1178 ? ? ? ? ? ? ? ? signals ??
Max msgqueue size ? ? ? ? 819200 ? ? ? ? ? ? ? 819200 ? ? ? ? ? ? ? bytes ? ??
Max nice priority ? ? ? ? 0 ? ? ? ? ? ? ? ? ? ?0 ? ? ? ? ? ? ? ? ? ?
Max realtime priority ? ? 0 ? ? ? ? ? ? ? ? ? ?0 ? ? ? ? ? ? ? ? ? ?
Max realtime timeout ? ? ?unlimited ? ? ? ? ? ?unlimited ? ? ? ? ? ?us

通过命令设置当前终端会话,最大文件描述符数量:

ulimit -n 1000000? ? ? ? ? ? ? ?## 默认数量:1024

确定某个进程打开的文件描述符数量

lsof -Pnl +M -p 进程ID | wc -l?

确定某个进程打开的文件描述符详细信息

lsof -Pnl +M -p 进程ID

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-09-15 02:20:34  更:2022-09-15 02:22:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 4:37:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码