草庐IT

tcp - 优雅退出 TcpListener.incoming()

coder 2023-09-19 原文

来自 rust 标准网络库:

let listener = TcpListener::bind(("127.0.0.1", port)).unwrap();

info!("Opened socket on localhost port {}", port);

// accept connections and process them serially
for stream in listener.incoming() {
    break;
}

info!("closed socket");

如何让听者停止倾听?它在 API 中表示,当监听器被删除时,它会停止。但是,如果 incoming() 是一个阻塞调用,我们如何丢弃它呢?最好没有像 tokio/mio 这样的外部 crate 。

最佳答案

您需要使用 set_nonblocking() 方法将 TcpListener 置于非阻塞模式,如下所示:

use std::io;
use std::net::TcpListener;

let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
listener.set_nonblocking(true).expect("Cannot set non-blocking");

for stream in listener.incoming() {
    match stream {
        Ok(s) => {
            // do something with the TcpStream
            handle_connection(s);
        }
        Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
            // Decide if we should exit
            break;
            // Decide if we should try to accept a connection again
            continue;
        }
        Err(e) => panic!("encountered IO error: {}", e),
    }
}

incoming() 调用将立即返回一个 Result<> 类型,而不是等待连接。如果 Result 为 Ok(),则连接已建立,您可以处理它。如果结果是 Err(WouldBlock),这实际上不是错误,只是在 incoming() 检查套接字的确切时刻没有挂起的连接。

请注意,在 WouldBlock 的情况下,您可能希望在继续之前放置一个 sleep() 或其他东西,否则您的程序将快速轮询 incoming() 函数以检查连接,从而导致 CPU 使用率过高。

代码示例改编自 here

关于tcp - 优雅退出 TcpListener.incoming(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56692961/

有关tcp - 优雅退出 TcpListener.incoming()的更多相关文章

  1. ruby-on-rails - Rails 优雅地处理超时 session ? - 2

    使用rails4,ruby2。我在rails配置中为我的cookiesession设置了30分钟的超时时间。问题是,如果我转到表单,让session超时,然后提交表单,我会收到此ActionController::InvalidAuthenticityToken错误。如何在Rails中优雅地处理这个错误?比如说,重定向到登录屏幕? 最佳答案 在您的ApplicationController:rescue_fromActionController::InvalidAuthenticityTokendoredirect_tosome_p

  2. ruby - 获取数组中的值并最小化某个类属性的最优雅的方法是什么? - 2

    假设我有以下类(class):classPersondefinitialize(name,age)@name=name@age=ageenddefget_agereturn@ageendend我有一组Person对象。是否有一种简洁的、类似于Ruby的方法来获取最小(或最大)年龄的人?如何根据它对它们进行排序? 最佳答案 这样做会:people_array.min_by(&:get_age)people_array.max_by(&:get_age)people_array.sort_by(&:get_age)

  3. ruby-on-rails - 优雅的 Rails : multiple routes, 相同的 Controller Action - 2

    让多条路线去同一条路的最优雅的方式是什么ControllerAction?我有:get'dashboard',to:'dashboard#index'get'dashboard/pending',to:'dashboard#index'get'dashboard/live',to:'dashboard#index'get'dashboard/sold',to:'dashboard#index'这很丑陋。有什么“更优雅”的建议吗?一个类轮的奖励积分。 最佳答案 为什么不只有一个路由和一个Controller操作,并根据传递给它的参数来

  4. ruby - 鸭子输入字符串、符号和数组的优雅方式? - 2

    这是针对我无法破坏的现有公共(public)API,但我确实希望对其进行扩展。目前,该方法采用字符串或符号或任何其他在作为第一个参数传递给send时有意义的内容我想添加发送字符串、符号等列表的功能。我可以只使用is_a吗?数组,但还有其他发送列表的方法,这不是很像ruby​​。我将调用列表中的map,所以第一个倾向是使用respond_to?:map。但是字符串也会响应:map,所以这行不通。 最佳答案 如何将它们全部视为数组?String的行为与仅包含String的Array相同:deffoo(obj,arg)[*arg].eac

  5. ruby - 在 ruby​​ 中生成一个进程,捕获 stdout,stderr,获取退出状态 - 2

    我想从ruby​​rake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调

  6. ruby - 优雅的链式 'or' 用于测试 Ruby 中的相同变量 - 2

    怎样说才是明智的呢?if@thing=="01"or"02"or"03"or"04"or"05"(数字包含在数据类型字符串的列中。) 最佳答案 制作数组并使用.include?if["01","02","03","04","05"].include?(@thing)如果值真的都是连续的,你可以使用像(1..5).include?这样的范围对于字符串,你可以使用:if("01".."05").include?(@thing) 关于ruby-优雅的链式'or'用于测试Ruby中的相同变量,我

  7. ruby - Ruby 中优雅的循环 Elsing - 2

    我必须编写一个Ruby方法:遍历数组,如果其中一个元素符合特定条件则执行Foo。如果没有数组元素符合条件,则执行Bar操作。在任何其他语言中,我会在进入循环之前设置一个bool变量,并在执行Foo时切换它。该变量的值会告诉我是否需要Bar。但这感觉不像Rubyish那样不优雅。谁能提出更好的方法?编辑一些非常好的答案,但由于我本应提及的细节,它们不太有效。Foo所做的事情是对符合条件的数组元素完成的。此外,保证最多有一个元素匹配条件。 最佳答案 是否有任何项目匹配?如果是,则做一些不涉及匹配项目的事情。ifitems.any?{|i

  8. ruby-on-rails - 如何在不退出 IRB session 的情况下退出调试器? - 2

    这是一个长期存在的挫败感来源,但也许我遗漏了什么。如果我正在调试,并且我想退出调试器并返回到IRB或Rails控制台,“退出”将不起作用,因为它将退出IRB。“完成”似乎也与继续具有相同的效果。使用“删除”删除断点然后尝试“继续”或“完成”不起作用。有什么想法吗? 最佳答案 至少在byebug中,你可以这样做:evalreturn它具有计算当前函数的return语句的净效果。这有时会奏效,具体取决于调用堆栈的外观。现在虽然这不会删除当前断点....如果您只是想收回控制权,在大多数情况下这会做到这一点,具体取决于您的代码结构。在您的代

  9. ruby - Thin::Server#daemonize 立即退出 - 2

    我试图制作一个可执行文件,它通过Thin作为守护进程启动Sinatra应用程序。我正在使用此代码通过Sinatra应用程序调用Thin:#!/usr/bin/envrubyrequire'thin'require'app.rb'server=::Thin::Server.new('127.0.0.1',9999,App)server.log_file='tmp/thin.log'server.pid_file='tmp/thin.pid'server.daemonize这是我执行脚本时得到的日志输出:>>WritingPIDtotmp/thin.pid>>Exiting!服务器正常启动

  10. ruby - 当 shelled-out 命令返回非零退出代码时,如何让 Ruby 脚本失败? - 2

    在Ruby脚本中,有variousways调用系统命令/命令行反引号:`commandarg1arg2`分隔形式,例如%x(commandarg1arg2)(可用其他分隔符)Kernel#system方法:system('commandarg1arg2')Kernel#exec方法:exec('commandarg1arg2')如果我希望Ruby脚本在调用的命令失败时失败(有异常)(具有非零退出代码),我可以检查特殊变量中的退出代码$?对于前两个变体:`commandarg1arg2`failunless$?==0或%x,commandarg1arg2,failunless$?==0如

随机推荐