代码之家  ›  专栏  ›  技术社区  ›  Beanish

在Ruby套接字中使用Select如果满足某个条件,那么忽略给定套接字的好方法是什么?

  •  0
  • Beanish  · 技术社区  · 14 年前

    一点背景:

    我已经编写了一个脚本,它将作为传入的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 回复  |  直到 14 年前
        1
  •  1
  •   Wayne Conrad    14 年前

    如果我回忆起, select 水平驱动,而不是边缘驱动。换句话说,如果 选择 返回描述符,下次调用 选择 它会再次告诉你。

    因此,如果您没有运行,您仍然需要读取数据(或其他适合事件的数据),或者 选择 稍后再告诉你。

    要确认我的假设,请在呼叫后立即打印“foo” 选择 ,制造 @running false 然后尝试建立连接。如果你看到“foo”一次又一次的嘲笑,显示select没有阻塞,那么我是对的。如果你不这样做,我会收回我的话/删除我的答案。

    作为旁白,你可以(也应该)简单地说 @跑步 而不是 @running == true !@running 而不是 @running == false