【问题标题】:Why doesn't Ruby's select return the socket?为什么 Ruby 的 select 不返回套接字?
【发布时间】:2010-10-09 06:20:11
【问题描述】:

我正在尝试在 STDIN 上使用 select 并在 Ruby 中使用 TCP 套接字,但由于某种原因,从 select 返回的值似乎永远不会匹配其中一个选项;看起来它是正在返回的套接字,但它与使用 == (或等于?)不匹配。谁能告诉我为什么从 select 返回的结果与我传入的对象不匹配,以及我应该在这里做些什么不同的事情?

server = TCPSocket::new("irc.freenode.net", 7000)
server.puts "NICK MyBot"
server.puts "USER #{ENV['USER']} 0 * :My Bot"

# <snip definitions>

while (!$done)
  results = select([server, STDIN], nil, nil)
  if results[0] == STDIN
    puts "Reading from STDIN"
    execute_command
  elsif results[0] == server
    puts "Reading from server"
    receive_data
  else
    puts "Something's wrong... results[0]: #{results[0]}, server: #{server}"
    puts "IDs: results[0]: #{results[0].__id__}, server: #{server.__id__}"
    exit 1
  end
end

这是我运行它时得到的结果:

出了点问题... 结果[0]: #<0x33c390><0x33c390>


    标签: ruby select sockets


    【解决方案1】:

    select 返回的 Array 的第一个元素是准备好的 IO 对象的 Array。因此,您应该将 STDIN 和服务器与 results[0][0] 进行比较。或者更好地检查,如果套接字在结果数组中

    ...
    if results[0].include? STDIN
      ...
    elsif results[0].include? server 
     ...
    ...
    

    【讨论】:

    • 是的,就是这样。我想我错过了结果是数组数组;令人困惑的是,该数组的打印结果与我的调试语句中的单个套接字完全相同。我结束了一个循环遍历结果 [0] 中的元素而不是使用 include?,但你的回答让我开始了。谢谢!
    • 啊,有趣。我忘记了通过“#{array}”打印数组只是打印元素。我猜打印语句调试的危险。 :)
    • 在 Ruby1.9 中这有所改进,[1, 2, 3].to_s 给出了“[1, 2, 3]”而不是“123”。在 1.8 中,您可以通过调用 Array#inspect 来获得此行为。
    【解决方案2】:

    如果你使用 .equal,你会得到相同的结果吗?还是 .eql?

    http://ruby-doc.org/core/classes/Object.html#M000341

    == 可以被子类覆盖,但是 .equal?不应该是。这里的主要问题实际上是为什么同一个对象,当通过 == 与自身进行比较时,返回 false。您可能需要查看 TCPSocket 类的源代码或文档。

    【讨论】:

    • 与 .equal 的结果相同吗?如果我尝试打印每个对象的 id,它们是不同的: puts "IDs: results[0]: #{results[0].__id__}, server: #{server.__id__}" Gives我:IDs: results[0]: 1695840, server: 1695990
    猜你喜欢
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多