[Q] Is there any way to do a non-blocking TCPSocket#recv?

W

Warren Brown

------_=_NextPart_001_01C4710A.C1A3D1B3
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

I am trying to create a simple socket monitor program in Ruby. The idea
is to listen for an "inbound" connection, then open an "outbound" socket
and forward all of the traffic both ways while logging the traffic. In
order to do this, I need to be able to tell if there is data available
to receive before doing the TCPSocket#recv, since #recv blocks if there
isn't any (instead of simply returning 0 bytes or nil). There is no
#select method in any of the classes to test for data availability, so
I'm stuck. I would think this is a common thing to want to do, but
there doesn't seem to be any way to do it using the socket library.
What am I missing?

=20

=20

Details:

=20

ruby 1.8.1 (2003-12-25) [i386-mswin32]

=20

=20

Sample code:

=20

def monitor

@outsock =3D TCPSocket.new(@outhost,@outport)

@inserver =3D TCPServer.new(@inhost,@inport)

while @insock =3D @inserver.accept

loop do

# ...

buffer =3D @insock.recv(BUFFER_SIZE) # Blocking call...

@outsock.send(buffer,0)

# ...

Buffer =3D @outsock.recv(BUFFER_SIZE) # Blocking call...

# @insock.send(buffer,0)

...

end

end

end

=20

=20

Thanks in advance for any help.

=20

- Warren Brown

=20


------_=_NextPart_001_01C4710A.C1A3D1B3--
 
J

Joel VanderWerf

Warren said:
I am trying to create a simple socket monitor program in Ruby. The idea
is to listen for an "inbound" connection, then open an "outbound" socket
and forward all of the traffic both ways while logging the traffic. In
order to do this, I need to be able to tell if there is data available
to receive before doing the TCPSocket#recv, since #recv blocks if there
isn't any (instead of simply returning 0 bytes or nil). There is no
#select method in any of the classes to test for data availability, so
I'm stuck. I would think this is a common thing to want to do, but
there doesn't seem to be any way to do it using the socket library.
What am I missing?

What about putting each socket handler in a thread and using two queues
to pass data between threads? (I'm ignorant, but I think internally ruby
will use select() to schedule these threads to run when data is coming in.)
 
Y

Yohanes Santoso

Warren Brown said:
isn't any (instead of simply returning 0 bytes or nil). There is no
#select method in any of the classes to test for data availability, so

IO.select.

Object begats IO. IO begats BasicSocket. BasicSocket begats
IPSocket. IPSocket begats TCPSocket. :)

So, there is a TCPSocket.select, but usually people use IO.select or
Kernel.select (all are just different names for the same thing).

YS.
 
A

Aredridel

I am trying to create a simple socket monitor program in Ruby. The idea
is to listen for an "inbound" connection, then open an "outbound" socket
and forward all of the traffic both ways while logging the traffic. In
order to do this, I need to be able to tell if there is data available
to receive before doing the TCPSocket#recv, since #recv blocks if there
isn't any (instead of simply returning 0 bytes or nil). There is no
#select method in any of the classes to test for data availability, so
I'm stuck. I would think this is a common thing to want to do, but
there doesn't seem to be any way to do it using the socket library.
What am I missing?

Use select anyway:

i,o,e = select([@insock, @outsock]) or similar.

Or use threads -- Ruby's threads use a select() call internally anyway.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top