2011-05-29 22 views
11

我有一些代码用于从网络套接字获取数据。它工作正常,但我通过反复试验挫败了自己的想法。我虚心承认,我不完全理解它是如何工作的,但我真的很想。 (这是货物culted形式运行的代码,我发现)在Ruby中读取套接字时了解IO.select

我不明白以“准备= IO.select ......”开始的部分我不清楚在:

  1. 什么IO.select是做(我试图寻找它,但得到更加混乱与内核和什么,而不是)
  2. 什么数组变量IO.select是
  3. 什么就绪[0]做
  4. 的总体思路读取1024个字节?同时

下面的代码:

@mysocket = TCPSocket.new('192.168.1.1', 9761) 

th = Thread.new do 
    while true 
     ready = IO.select([@mysocket]) 
     readable = ready[0] 

     readable.each do |socket| 
      if socket == @mysocket 
       buf = @mysocket.recv_nonblock(1024) 
       if buf.length == 0 
        puts "The server connection is dead. Exiting." 
        exit 
       else 
        puts "Received a message" 
       end 
      end 
     end 

    end 
end 

预先感谢帮助我“学会鱼”。我讨厌我的代码片断,我不完全理解 - 这只是巧合。

+0

但是,为什么使用新的线程?那有什么优点和缺点? – DiegoSalazar 2012-07-27 22:33:48

+0

我跑了这个例子,在里面放了一堆'puts',并且不明白为什么程序永远不会进入'while true'循环(或者可能是'puts'输出在循环内部永远不会到达控制台?) – Paul 2014-05-26 13:57:39

回答

17

1)IO.select需要一组套接字并等待,直到可以读取或写入它们(或者如果发生错误)。它返回发生的套接字事件。

2)数组包含检查事件的套接字。在你的情况下,你只指定套接字来读取。

3)IO.select返回一个套接字数组数组。元素0包含您可以读取的套接字,元素1 - 您可以写入的套接字以及元素2 - 包含错误的套接字。

获取套接字列表后,您可以读取数据。

4)是,recv_nonblock参数是以字节为单位的大小。请注意,实际读取的数据大小可能小于1024,在这种情况下,您可能需要重复select(如果实际数据对您很重要)。

+0

所以基本上这是不使用带有超时参数的select来确定套接字是否处于活动状态,而是使用#recv来检查是否有可能获得大约1024个字节的数据,如果不是,它会确定套接字已死,对吧? ?但是,那么......如果现在没有数据需要读取(可能会晚点)呢?这种检查如何能够确定一个连接是否已经死亡的好方法? ..我没有收到什么(大?)部分?谢谢.. – 2013-03-09 05:01:19