使用带有ruby套接字的Select,如果满足某个条件,忽略给定套接字的好方法是什么?

时间:2010-02-04 20:32:30

标签: ruby select sockets

一点背景:

我编写了一个脚本,它将充当传入的Syslog / Email / Snmp(v1)陷阱的接收器。它接收数据并将其存储为自定义对象。我的“messageSocket”是一种从一般侦听器之外的脚本控制行为的方法。我想向此发送消息以启动/停止命令。启动/停止基本上只是改变了@running变量的状态。

所有这一切都运行正常,除非我停止 - 如果我触发创建电子邮件/陷阱等的事件,则在@running = false时不会注册。但是,只要我设置@running = true,它仍会看到此套接字数据并进行分析。

我尝试从@descriptors数组中删除给定的套接字,我尝试关闭套接字,我尝试将res设置为不同的值。我猜我现在只是缺少一些东西,任何帮助或指导都会非常感激!

def run()  
   while 1 == 1

     res = select(@descriptors, nil, nil, nil)

     if res != nil then

        for sock in res[0]
          if sock == @mailSocket && @running == true then
            accept_new_connection
          elsif sock == @sysSocket && @running == true then
            get_syslog_message
          elsif sock == @snmpSocket && @running == true then
            get_snmp_message
          elsif sock == @mailSocket && @running == false then
            reject_mail
          elsif sock == @messageSocket then
            get_message()
          elsif sock == @snmpSocket && @running == false then
            #do something
          elsif sock == @sysSocket && @running == false then
            #do something
          end
        end   
      end
    end
 end
   #run end 
  end

1 个答案:

答案 0 :(得分:1)

如果我记得,select是(某种)等级驱动的,而不是边缘驱动的。换句话说,如果select返回描述符而您对这些描述符不做任何操作,则下次调用select时它会再次告诉您。

因此,如果您没有运行,您仍然必须阅读数据(或其他任何适合该事件的数据),或select稍后会再次告诉您。

要确认我的假设,请在致电select后立即打印“foo”,将@running设为false,然后尝试建立连接。如果你看到“foo”一遍又一遍地骂,表明选择没有阻止,那我就是对的。如果你不这样做,我会吃掉我的话/删除我的答案。

顺便说一下,您可以(而且应该)简单地说@running而不是@running == true,而!@running代替@running == false