TCPSocket Flushing

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

2007/8/13, David – [email protected]:

connection.write “one\n”
while not sock.eof?
print sock.read
end

As far as I can see you read the whole stream in one go with
sock.read. Try this instead

sock.each_line do |line|
puts line
end

Kind regards

robert

As far as I can see you read the whole stream in one go with
sock.read. Try this instead

sock.each_line do |line|
puts line
end

Kind regards

robert

It worked perfectly, thank you.

In article [email protected],
David – [email protected] writes:

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.

  • dmw

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:

In article [email protected],
David – [email protected] writes:

connection.write “one\n”
while not sock.eof?
print sock.read
end

I agree–I wish Ruby had a comprehensive documentation+wiki (or
documentation with comments). Anyone want to help with that one? :slight_smile:
-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.

On Aug 14, 2007, at 21:46, Roger P. wrote:

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.
I agree–I wish Ruby had a comprehensive documentation+wiki (or
documentation with comments). Anyone want to help with that one? :slight_smile:

See ruby-doc.org and the mailing list at [email protected].

The best way to contribute to documentation is submit RDoc patches.

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.

On 15.08.2007 06:46, Roger P. wrote:

I agree–I wish Ruby had a comprehensive documentation+wiki (or
documentation with comments). Anyone want to help with that one? :slight_smile:

The pickaxe is pretty comprehensive and has good examples IMHO.

Cheers

robert

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.

n 8/12/07, David – [email protected] wrote:

while connection = server.accept
sock = TCPSocket.open(“localhost”, 2000)
while not sock.eof?
print sock.read
end

Posted via http://www.ruby-forum.com/.

Did you try using IO#close_write?

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.

2007/8/21, Roger P. [email protected]:

My question is: what is the ‘write’ equivalent of ‘recv’ (i.e. write non
blocking) for sockets…hmm…

I believe the pairing is read-write and send-recv.

robert

Thanks!
Robert K. wrote:

2007/8/21, Roger P. [email protected]:

My question is: what is the ‘write’ equivalent of ‘recv’ (i.e. write non
blocking) for sockets…hmm…

I believe the pairing is read-write and send-recv.

robert