From: Ernie Date: 2002-12-20T01:16:39+09:00 Subject: Re: Socket problem "Child" wrote in message news:slrnb02blb.ejn.child@child.t9.ds.pwr.wroc.pl... > Hello > > I am new to ruby, but I think it's excellent language - no doubt the > best one (cleanest, fastest to write in etc.) I ever used :) > > I'm trying to write a NNTP client and I encountered some problems with > sockets. I have to read server response from socket. The response is > multiline and ends with ".\r\n". Is there any way to get whole response > at once? At the moment I use gets and read the response line by line, > which is horribly inefficient. In C program I used ioctl FIONREAD call > to read number of available bytes and then fetched them with read, but > can't get this call working in ruby - always get "Bad address > (Errno::EFAULT" error. And if I use recv with arbitrary number (eg. > 10000) it hangs forever. > > Thanks for any help. > > -- > Marek Janukowicz > http://starware.one.pl Below is a pretty basic server that makes use of "select" to do what you want to do. You have to be a little careful with "select". I returns nil if nothing is going on with the read end of the socket. If something is there to read. It will return an array. However, it will also return an array of three empty arrays if the socket is closed on the other end, at least it does in Windows. Thus, the begin and rescue sections. Of course I'm assuming the protocol you are using doesn't permit lines with only a \r\n unless the line marks the end of the data. class SocketProc def initalize(session) @sess=session end def readIn() dataIn="" while true begin foo=select([@sess],nil, nil, timeoutvalue) if foo bar=@sess.readline @dataIn.concat(bar) break if bar=~/^\r\n/ end rescue @sess.close end end processData (dataIn) end def processData(dataIn) #do what you want including writing to @sess @sess.close end end server=TCPServer.new(port) BasicSocket.do_not_reverse_lookup=true #the do_not_reverse_lookup is necessary if you want some speed. By default it is false. while (session=server.accept) do Thread.new(session) do |aSession| z=SocketProc.new(aSession) while aSession z.readIn end end end