【问题标题】:Ruby TCPSocket: Find out how much data is availableRuby TCPSocket:找出有多少数据可用
【发布时间】:2011-04-28 09:04:37
【问题描述】:

有没有办法在 Ruby 中找出 TCPSocket 上可用的数据字节数? IE。不阻塞可以准备多少字节?

【问题讨论】:

    标签: ruby sockets nonblocking tcpsocket


    【解决方案1】:

    标准库io/wait 可能在这里有用。要求它为基于流的 I/O(套接字和管道)提供了一些新方法,其中包括 ready?。根据documentation,准备好了吗?如果有可用的字节而不阻塞,则返回非零。碰巧它返回的非零值是 MRI 中可用的字节数

    这是一个示例,它创建了一个愚蠢的小套接字服务器,然后通过客户端连接到它。服务器只是发送“foo”然后关闭连接。客户端稍等片刻,让服务器有时间发送,然后打印有多少字节可供读取。对你来说有趣的东西在客户端:

    require 'socket'
    require 'io/wait'
    
    # Server
    
    server_socket = TCPServer.new('localhost', 0)
    port = server_socket.addr[1]
    Thread.new do
      session = server_socket.accept
      sleep 0.5
      session.puts "foo"
      session.close
    end
    
    # Client
    
    client_socket = TCPSocket.new('localhost', port)
    puts client_socket.ready?    # => nil
    sleep 1
    puts client_socket.ready?    # => 4
    

    不要在任何实际中使用该服务器代码。为了使示例简单,它被故意延迟。

    注意:根据 Pickaxe 书,io/wait 仅在“ioctl(2) 中的 FIONREAD 功能”时可用。它在Linux中。我不了解 Windows 和其他。

    【讨论】:

    • 你知道它是否适用于 JRuby 吗?
    • @panzi,我不知道 JRuby,所以我不知道。此页面表明该功能可能可用,但使用与 MRI 不同的类:jruby.org/apidocs/org/jruby/util/io/CRLFStreamWrapper.html(向下滚动至ready?)。
    • 我在JRuby下试过了。该方法在那里,但如果可以读取某些内容,它只会返回1 而不是实际数量。好吧,没有这个我可以实现它,但它会更有效率。
    • @panzi,我想知道 ready? 返回计数是否是 MRI 的一个怪癖。现在你已经确认它是。我很抱歉带你走上错误的道路。
    • 我正在使用 SSLSocket。函数 .ready 了吗?那里似乎不存在。我可以在 SSLSocket 上使用任何其他功能吗?