Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Ruby中的TCPSocket读取_Ruby_Sockets_Tcp - Fatal编程技术网

从Ruby中的TCPSocket读取

从Ruby中的TCPSocket读取,ruby,sockets,tcp,Ruby,Sockets,Tcp,此代码向www.example.com网站发送两个HTTP请求: require 'socket' @host = 'www.example.com' @port = 80 @path = "/" # Build HTTP request def request(close=false) "GET #{@path} HTTP/1.1\r\nHost: #{@host}#{"\r\nConnection: close" if close}\r\n\r\n" end # Build soc

此代码向www.example.com网站发送两个HTTP请求:

require 'socket'

@host = 'www.example.com'
@port = 80
@path = "/"

# Build HTTP request
def request(close=false)
  "GET #{@path} HTTP/1.1\r\nHost: #{@host}#{"\r\nConnection: close" if close}\r\n\r\n"
end

# Build socket
socket = TCPSocket.open(@host,@port)  # Connect to server

# Send request twice via socket
2.times {socket.print request}
以下是我找到的阅读回复的各种方法:

# Method 1: close_write and read
socket.close_write # Without this line, the next line hangs
response = socket.read
puts response.length

# Method 2: send another http request with 'Connection: close' header, then use 'read'
socket.print request(true) # Without this line, the next line hangs
response = socket.read
puts response.length

# Method 3: recv
# puts socket.eof?  # Method fails when I add this line
r1, r2 = socket.recv(1000000), socket.recv(1000000)
puts r1.length, r2.length

# Method 4: IO.select and read_nonblock
puts socket.eof?
# IO.select([socket])  # The code still works without this IO.select...
r1 = socket.read_nonblock(9999999)
IO.select([socket])  # ...but not without this one
r2 = socket.read_nonblock(9999999)
puts r1.length, r2.length
puts socket.eof? # Hangs for ages before returning 'true'
问题:

  • 方法1中的“socket.close_write”行到底在做什么?为什么该方法必须工作
  • 在方法2中,“Connection:close”头是否以某种方式实现了与方法1中的“socket.close\u write”行相同的结果?如果没有,它在做什么,为什么该方法的其余部分必须工作
  • 为什么在方法3中,添加注释行“puts socket.eof”会导致其余代码挂起
  • 在方法3中,recv调用如何以及为什么在HTTP响应结束时停止(而不是拾取下一个响应)
  • 为什么方法4中的第二个IO.select是必需的,而第一个不是必需的
  • IO.select实际上做什么
  • 为什么方法4中的最后一行“puts socket.eof?”在返回true之前会挂起很长时间
  • 是否有一种常规方法可以检查套接字当前期望的响应数量,并从套接字读取该数量的响应,而无需关闭套接字进行写入 最后,如果在这里的回答中不可能,那么是否有一个好的资源,我可以在其中对上述所有内容进行一些澄清,并对从TCP套接字(或网络套接字)读取数据进行总体澄清


    谢谢。

    套接字。无需关闭\u write
    。我的意思是,你可以通过
    socket.read
    获得socket返回的内容,但你需要等待一段时间。原因是您试图使用
    socket.read
    在一个流中读取整个流。这需要时间。您可以通过执行以下操作了解套接字返回的内容:

    socket.each_line do |line|
      puts line
    end
    
    顺便说一句,这也让它变慢了

    close\u write
    所做的是让客户端半关闭套接字。当服务器端注意到这一点时,它也会关闭其端。这样你就可以很快读完

    或者您可以使用
    IO::select
    。如上所述:

    它监视给定的IO对象数组,等待一个或多个IO对象准备读取,准备写入,并分别具有挂起的异常,然后返回包含这些IO对象数组的数组。如果给定了可选的超时值,并且在超时秒内没有IO对象就绪,它将返回nil


    这里我们传递第一个参数,它是准备读取的对象
    ,最后一个参数是要设置的超时。这意味着如果读数在10秒内未准备就绪,它将返回nil,然后引发超时错误

    套接字。无需关闭\u write
    。我的意思是,你可以通过
    socket.read
    获得socket返回的内容,但你需要等待一段时间。原因是您试图使用
    socket.read
    在一个流中读取整个流。这需要时间。您可以通过执行以下操作了解套接字返回的内容:

    socket.each_line do |line|
      puts line
    end
    
    顺便说一句,这也让它变慢了

    close\u write
    所做的是让客户端半关闭套接字。当服务器端注意到这一点时,它也会关闭其端。这样你就可以很快读完

    或者您可以使用
    IO::select
    。如上所述:

    它监视给定的IO对象数组,等待一个或多个IO对象准备读取,准备写入,并分别具有挂起的异常,然后返回包含这些IO对象数组的数组。如果给定了可选的超时值,并且在超时秒内没有IO对象就绪,它将返回nil


    这里我们传递第一个参数,它是准备读取的对象
    ,最后一个参数是要设置的超时。这意味着如果读数在10秒内未准备就绪,它将返回nil,然后引发超时错误

    谢谢。在我使用socket.close\u write之后,服务器如何“注意到”套接字已半关闭?这段代码实际上是做什么的?它向服务器发送了什么吗?谢谢。在我使用socket.close\u write之后,服务器如何“注意到”套接字已半关闭?这段代码实际上是做什么的?它是否向服务器发送了内容?