【问题标题】:How do I make persistent network sockets on Unix in Ruby?如何在 Ruby 中的 Unix 上创建持久网络套接字?
【发布时间】:2010-09-07 12:07:07
【问题描述】:

我希望能够编写一个 ruby​​ 程序,它可以在不中断套接字连接的情况下重新启动。

【问题讨论】:

    标签: ruby sockets


    【解决方案1】:

    您说的是网络套接字,而不是我认为的 UNIX 套接字?

    我不确定这是否适合您的需求,但我的做法是将网络和逻辑部分分开,只重新启动逻辑部分,然后将逻辑部分重新连接到网络部分。

    【讨论】:

      【解决方案2】:

      该程序获取 Google 的主页,然后当您通过 Ctrl-C 向它传递 SIG_INT 时,它会重新启动程序并使用 Google 从打开的套接字读取主页的输出.

      #!/usr/bin/ruby
      #simple_connector.rb
      require 'socket'
      
      puts "Started."
      
      if ARGV[0] == "restart"
        sock = IO.open(ARGV[1].to_i)
        puts sock.read
        exit
      else
        sock = TCPSocket.new('google.com', 80)
        sock.write("GET /\n")
      end
      
      Signal.trap("INT") do
        puts "Restarting..."
        exec("ruby simple_connector.rb restart #{sock.fileno}")
      end
      
      while true
        sleep 1
      end
      

      【讨论】:

      • 重启时:simple_connector.rb:8:in initialize': Bad file descriptor (Errno::EBADF) from simple_connector.rb:8:in open' from simple_connector.rb:8:in `
        '
      • From ruby-doc.org/core-2.1.2/IO.html#method-i-close_on_exec-3D Ruby 自 Ruby 2.0.0 起默认设置所有文件描述符的 close-on-exec 标志。所以不需要自己设置。此外,如果另一个线程使用 fork() 和 exec()(例如通过 system() 方法),取消设置 close-on-exec 标志可能会导致文件描述符泄漏。如果确实需要子进程继承文件描述符,请使用 spawn() 的参数,例如 fd=>fd。
      • 我所做的 - 以你的例子为例,没有任何改变。您能否提供一个示例如何以正确的方式处理 close-on-exec 标志?我应该在执行之前简单地将其设置为 true 吗?
      • 我搞砸了一些,但我没有想出一个功能齐全的例子。而不是execspawn("ruby simple_connector.rb restart #{sock.fileno}", sock=>sock)。不幸的是,我认为 spawn 在其他方面也与 exec 不同。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多