keymi 2008-8-22 15:47
用ruby进行socket编程的问题??
请问,用ruby进行socket编程时,如何用select实现异步IO的方法。
我现在编写的程序,用recv接收数据,但是当没有数据时,就阻塞住了,我想用select实现在3秒没有接收到数据就跳出,如何做呢?
最好有例子,谢谢!!
Hozaka 2008-8-22 17:47
虽然不清楚具体的需求,但是如果想做超时的控制,可以用 Timeout。
例子和文档在 [url]http://ruby-doc.org/core/classes/Timeout.html[/url]
keymi 2008-8-25 14:04
先谢谢2楼的回答哈,我不是要实现超时,是在用socket编程时,它在recv数据的时候,会等待,接收到数据就放到缓冲里,但是没有接受到,它就会等在这里,阻塞住了,不往下运行了。
而用select的话,可以让这个recv在一定时间内,如果没有接受到数据,就不等了,但是这个select语句,我现在不回用耶!
希望有会socket编程的高手帮忙解答下!!谢谢!
Hozaka 2008-8-25 15:51
[quote]
可以让这个recv在一定时间内,如果没有接受到数据,就不等了
[/quote]
不就是超时么……
用 Timeout 可以在设定时间内尝试执行代码块,如果超过指定的时间,中止代码的执行并抛出异常
keymi 2008-8-26 09:31
因为timeout是以Thread来实现的, 若在C层面上失去响应的话(不会进行Thread切换), 它就无能为力了。
而这个recv恰恰就是上面的情况,程序实际就停在recv这个函数的位置了,所以执行不下去了,我用了timeout试过,不行,每次都超时了,这种方法似乎不太行啊。
不过还是感谢楼上的,非常感谢哈!!
sw2wolf 2008-8-26 11:09
# In one script, start this first
require 'socket'
include Socket::Constants
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(2200, 'localhost')
socket.bind(sockaddr)
socket.listen(5)
begin
client_socket, client_sockaddr = socket.accept_nonblock
rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR
IO.select([socket])
retry
end
puts "The client said, '#{client_socket.readline.chomp}'"
client_socket.puts "Hello from script one!"
socket.close
# In another script, start this second
require 'socket'
include Socket::Constants
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(2200, 'localhost')
socket.connect(sockaddr)
socket.puts "Hello from script 2."
puts "The server said, '#{socket.readline.chomp}'"
socket.close
keymi 2008-8-29 09:15
谢谢楼上的各位!!
最后我用的是 Thread 线程的思想,我开了两个线程,一个去进行socket操作,一个用来监视第一个线程,判断其超时还没有返回,就会强行把线程关闭,从而解决了 recv 阻塞的问题~!:victory: