[英]Reading from a TCPSocket in Ruby
此代码将两个HTTP请求发送到www.example.com网站:
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'
问题:
最后,如果这里不可能提供答案,那么是否有足够的资源可以使我对上述所有内容有所了解,并且可以从读取TCP套接字(或一般来说是网络套接字)中获得大致的了解?
谢谢。
不需要socket.close_write
。 我的意思是,您可以通过socket.read
获得套接字返回的socket.read
,但是您将要等待一段时间。 原因是因为您试图使用socket.read
读取整个流。 这需要时间。 您可以通过执行以下操作来找出套接字返回的内容:
socket.each_line do |line|
puts line
end
顺便说一句, Nagle的算法也使它变慢。
close_write
作用是让客户端半关闭套接字,当服务器端注意到这一点时,它也将关闭它的一侧。 然后,您可以非常快速地完成阅读。
或者您可以使用IO::select
。如文档所述:
它监视给定的IO对象数组,等待一个或多个IO对象准备好读取,准备好写入并分别具有待处理的异常,并返回包含这些IO对象的数组的数组。 如果给出了可选的超时值,并且在超时秒数内没有IO对象准备就绪,它将返回nil。
ready = IO.select([socket], nil, nil, 10)
if ready
# do something
else
# raise timeout
end
在这里,我们传递第一个参数,它是ready for reading
的对象,最后一个是您要设置的超时。 这意味着,如果10秒钟后仍未准备好读数,它将返回nil,然后引发超时错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.