【问题标题】:How should I close a socket in a signal handler?我应该如何关闭信号处理程序中的套接字?
【发布时间】:2009-01-16 05:48:41
【问题描述】:

我正在编写一个非常简单的服务器,它会一直循环直到按下 Ctrl-C。我想让 ctrl-c 的信号处理程序关闭打开的套接字并关闭服务器,但我不知道信号处理程序的范围是什么,我不喜欢声明套接字的想法(s) 我需要关闭才能成为全球性的。

有人可以提供建议吗?有没有一些标准的方法来做到这一点?

【问题讨论】:

    标签: sockets signals interrupt


    【解决方案1】:

    好吧,既然您有信号处理程序,我将假设您使用的是 Unix 变体。如果是这样:

    • 内核通过文件号识别套接字,该文件号是一个 int。见socket(2)
    • 该 int 对您的进程有效
    • 该 int 对创建后派生的任何进程都有效
    • 如果不是 close-on-exec,它对您执行的任何进程都有效。

    因此,它在您的信号处理程序中完全有效。如何让信号处理程序知道要使用哪个数字取决于您编写的语言,您没有指定。有两种方法几乎适用于任何语言

    • 如果除了close 和退出之外没有任何清理工作要做,只需调用exit。或者将信号动作设置为默认值,即退出。内核将关闭套接字。
    • 设置一个标志(通常是某种全局的)来告诉您的选择/轮询循环清理并退出。好处在于您不必担心程序的各个部分是否可以安全地从信号处理程序中调用。

    【讨论】:

    • 操作系统不负责调用关闭后的清理吗?
    • @Bionix1441 我想这是关于第二个要点“清理并退出”的问题?我的意思是,您的程序可能需要进行 other 清理(例如,保存修改后的数据、删除锁定文件……)。这在信号处理程序之外要容易得多。
    【解决方案2】:

    通常,建议不要在信号处理程序中做太多事情;除了设置一个标志。

    然后当控制权返回到你的主循环时,你可以检查这个标志,退出循环,关闭套接字,在你的对象上运行析构函数等等,然后干净地退出。

    信号处理程序几乎可以在任何时候被调用,包括在 C 或 C++ 库调用的中间,这可能是个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-04
      • 1970-01-01
      • 1970-01-01
      • 2012-05-15
      • 1970-01-01
      • 2022-10-24
      • 2012-02-08
      相关资源
      最近更新 更多