I have two programs, a server and a client. I want to send two messages
to the client when the client connects to the server, with a delay in
between. However, both messages seem to arrive at the client at the same
time. Here are the programs:
simpleserver.rb
run this first
require “socket”
server = TCPServer.new(2000)
while connection = server.accept
connection.write “one\n”
connection.flush
sleep 1
connection.write “two\n”
connection.close
end
client.rb
run this second
require “socket”
sock = TCPSocket.open(“localhost”, 2000)
while not sock.eof?
print sock.read
end
connection.write “one\n”
while not sock.eof?
print sock.read
end
If the format of your server “messages” is always lines, i.e.,
strings terminated by new-lines and/or carriage-return/line-feeds,
then you should be able to just replace the read with a gets,
e.g.:
require "socket"
sock = TCPSocket.open("localhost", 2000)
while not sock.eof?
print sock.gets
end
If that is not the case, you will need to use something like the
following technique:
require "socket"
sock = TCPSocket.open("localhost", 2000)
loop do
str = sock.recv(100)
break if str.length == 0
print str
end
I have encountered the same problem in the past and I have looked
in vain for any documentation on the subject. So, the following
is pure supposition on my part, but it reflects my experience in
using sockets in Ruby:
I think that this is due to the magic of sockets in Ruby: you can
use a socket as either a socket object or as an IO object. Once
you use it as an IO object, however, it effectively becomes an IO
object and certain socket operations can no longer be used. So,
once you use either the eof? or read operations, the socket switches
to IO object mode, (i.e., buffered data) and the read call will block
until either the entire read is complete or an EOF occurs. Since
you didn’t specify any size of the read operation, it blocks until
it has read the entire “file.” Even if you had specified a size
to the read operation, it would have blocked until an entire buffer
of that size was filled (or EOF). Limiting the operations to those
available for sockets (e.g., recv) avoids this problem.
Yeah try using socket.recv(1024) or what not. I don’t know what read
does–it might wait until it closes to it can read the entire thing
‘once’ --as stated typically read (with files) reads the
entire file into one large string–not sure if it does so here, or tries
to, as well,
or not. Good luck.
-Roger
Belief is good. free bible - Google Search
Douglas Wells wrote:
I agree–I wish Ruby had a comprehensive documentation+wiki (or
documentation with comments). Anyone want to help with that one?
-Roger
David – wrote:
Ruby seems to be lacking in its documentation of sockets, unless I’m
just looking in the wrong places. I hadn’t seen anything about the
Socket::recv method. Thanks for all the help though, everyone.
Ruby seems to be lacking in its documentation of sockets, unless I’m
just looking in the wrong places. I hadn’t seen anything about the
Socket::recv method. Thanks for all the help though, everyone.
I agree–I wish Ruby had a comprehensive documentation+wiki (or
documentation with comments). Anyone want to help with that one?
Ruby seems to be lacking in its documentation of sockets, unless I’m
just looking in the wrong places. I hadn’t seen anything about the
Socket::recv method. Thanks for all the help though, everyone.
My question is: what is the ‘write’ equivalent of ‘recv’ (i.e. write non
blocking) for sockets…hmm…
David – wrote:
Ruby seems to be lacking in its documentation of sockets, unless I’m
just looking in the wrong places. I hadn’t seen anything about the
Socket::recv method. Thanks for all the help though, everyone.
The solution of reading the input in the client works well enough if you
know the data is line-structured, and if you have a positive way of
knowing
when you’ve read it all. Sometimes you have to deal with a client that
just
reads the input until it jams. (Programs intended to be used in Unix
pipelines often work this way.) In these cases, it can help to call
IO#close_write on the server side. That causes IO#read in the client to
return.
Someone recently did put up a Wiki-version of the documentation for Ruby
and
a big pile of the public Rubygems. Looked pretty good but I don’t know
if
it’s being successful.