查看完整版本: 用ruby进行socket编程的问题??

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:
页: [1]
查看完整版本: 用ruby进行socket编程的问题??