Ruby中socket编程时出现recv for buffered IO (IOError) 错误的解决方法

原创 2006年05月25日 13:24:00

Socket作异步编程时,检验对端是否已经关闭不能用Socket#eof?,因为这样会造成Ruby将此SocketIO对象转换成Buffered IO,从而导致recvrecvfrom系列函数读取失败,出现“recv for buffered IO (IOError)”错误。在Buffered IO上只能调用可能会阻塞的readreadlinegets系列函数,严重影响了异步通信服务器的性能。

 

我也被这个问题困扰了好几天,直到在ruby新闻组中看到一篇很好的解决方案,用异常代替eof?检查,我已经在ruby1.8.2 windows one-click版本上测试通过,特此引用。原帖可在http://groups.google.com/group/comp.lang.ruby/msg/3fabd75cf9a38c1c上找到。

 

顺便补一句,几乎所有的教学资料上都使用Socket#eof?这个方法,而很少谈到这个错误,真是很奇怪。

 

Socket programming: recv(bytes) throwing a buffered IO error


Frank Swarbrick <info...@earthlink.net>

Eric Haase wrote:
> Hello everyone,

>         I just started learning Ruby and I decided to mess around with
> socket programming. However, I've encountered a problem and was
> wondering if someone could help me out. I wrote a server and a client
> program and the server is behaving strange when I invoke the
> recv(bytes) method in the TCPSocket class. Here is my server code with
> the error I'm receiving:

> require 'socket'

> abort "usage: #{__FILE__} [port]" if ARGV.size > 1

> port = (ARGV[0] || 3434).to_i
> server = TCPServer.new(port)
> sockets = [server]

> puts "listening on port ##{port}"
> loop do
>   socketsReady = select(sockets)
>   next if socketsReady == nil
>   socketsReady[0].each do |socket|
>     if socket == server
>       client = socket.accept
>       sockets.push(client)
>       puts "established connection
> (#{client.addr[-1]}:#{client.addr[1]})"
>     else
>       if socket.eof?
>         address = socket.addr
>         sockets.delete(socket)
>         socket.close
>         puts "closed connection (#{address[-1]}:#{address[1]})"
>       else
>         string = socket.recv(1024)
>         puts "received /"#{string}/"
> (#{socket.addr[-1]}:#{socket.addr[1]})"
>         socket.puts("  server received your /"#{string}/"")
>       end
>     end
>   end
> end

> ./server_bad.rb:27:in `recv': recv for buffered IO (IOError)
>         from ./server_bad.rb:27
>         from ./server_bad.rb:15
>         from ./server_bad.rb:12

I'm not sure about all of the issues, but I think it may have to do with
you attempting to test socket.eof? prior to reading from socket.  I
don't think it can know about it's eof status until it does the read.

I'm just a Ruby beginner, but I know socket programming pretty well.
Try replacing the inside of the socketsReady[0].each loop as follows:

     if socket == server
       client = socket.accept
       sockets.push(client)
       puts "established connection" +
         "(#{client.addr[-1]}:#{client.addr[1]})"
     else
       begin
         string = socket.recv(1024)
         puts "received /"#{string}/""+
           "(#{socket.addr[-1]}:#{socket.addr[1]})"
         socket.write("  server received your /"#{string}/"")
       rescue
         address = socket.addr
         sockets.delete(socket)
         socket.close
         puts "closed connection (#{address[-1]}:#{address[1]})"
       end
     end

Seems to work.  Now you need to figure out how to abort from the loop,
such as when the user enters a key (on the server process).  I can't
figure it out...

Frank

 

Buffer I/O Error in /var/log/messages

主机报错信息:
  • kinges
  • kinges
  • 2014年10月24日 12:58
  • 3376

CentOS7.0开机报错end_request IO error dev fd0 sector 0

开机按F2进入BIOS,把软驱禁掉http://s3.51cto.com/wyfs02/M02/59/3D/wKioL1TMnWOwnwKeAAW4-BQgKPQ492.bmp...
  • u011404495
  • u011404495
  • 2017年02月05日 22:35
  • 1132

Python中BufferedIOBase

class io.BufferedIOBase   是支持某些缓冲区的二进制流的基类。它继承自IOBase,没有公共的构造器。和RawIOBase主要的区别在于,方法read(),readinto(...
  • jeryjeryjery
  • jeryjeryjery
  • 2017年05月29日 19:32
  • 503

解决log4j BufferedIO=true 时,buffer有残余日志不能记录的问题

废话不说,直接上代码 public class DailyRollingFileAppender extends org.apache.log4j.DailyRollingFile...
  • mochinoname
  • mochinoname
  • 2012年01月05日 21:12
  • 4653

使用Spring JDBC时遇到的Software caused connection abort: recv failed问题

在使用Spring jdbc连接数据库时遇到一个头疼的问题:程序启动以后,如果长时间不访问调用,当再次调用时会报错:  引用 org.springframework.dao.DataA...
  • guoyf123321
  • guoyf123321
  • 2015年12月13日 22:12
  • 5784

asp.net使用uploadify上传出现的IO Error问题

asp.net利用uploadfiy上传大文件IO失败问题
  • W3031213101
  • W3031213101
  • 2011年04月20日 13:44
  • 11431

log4j日志优化:使用BufferedIO和BufferSize而不是ImmediateFlush

之前我们使用FileAppender的时候,我们配置是ImmediateFlush=true,一旦有新日志写入,立马将日志写入到磁盘的文件中。当日志很多,这种频繁操作文件显然性能很低下。可以发现:日志...
  • aitangyong
  • aitangyong
  • 2015年12月24日 15:53
  • 6115

有关错误:buffer i/o error on device fd0,logical block 0

今天在给教研室的台式机装linux的时候,遇到了如下的错误buffer i/o error on device fd0,logical block 0。上网百度之后,发现是加载了软驱所导致的,所以只要...
  • bush2582
  • bush2582
  • 2013年11月02日 22:24
  • 4434

使用uploadify上传文件一直报IO error的原因

本周做项目使用了uploadify插件进行上传文件的处理,因为是上传mp3音频文件,所以文件大小一般在5M左右的大小。项目中其他地方也有使用uploadify插件,是用来上传jpg等图片资源的,一直都...
  • u011120720
  • u011120720
  • 2016年05月15日 23:31
  • 2550

开发:异常收集之 Software caused connection abort: recv failed

近期用ibatis比较多,中间也遇到很多奇葩小问题,但是也纠结我特别久。遂记录下来: 其中一个:java.sql.SQLException: Io 异常: Software caused c...
  • shijing266
  • shijing266
  • 2014年12月09日 11:43
  • 4015
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Ruby中socket编程时出现recv for buffered IO (IOError) 错误的解决方法
举报原因:
原因补充:

(最多只允许输入30个字)