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

···

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

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

···

2007/8/13, David -- <neko18@gmail.com>:

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

In article <18e16d93f4d0a9e65517e49c497bcfcd@ruby-forum.com>,
  David -- <neko18@gmail.com> writes:

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

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

···

--
. Douglas Wells . Connection Technologies .
. Internet: -sp9804- -at - contek.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.

···

n 8/12/07, David -- <neko18@gmail.com> wrote:

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
--
Posted via http://www.ruby-forum.com/\.

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.

···

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

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 <18e16d93f4d0a9e65517e49c497bcfcd@ruby-forum.com>,
  David -- <neko18@gmail.com> writes:

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

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

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.

···

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

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.

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

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.

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

See ruby-doc.org and the mailing list at ruby-doc@ruby-lang.org.

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

···

On Aug 14, 2007, at 21:46, Roger Pack 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:

--
Poor workers blame their tools. Good workers build better tools. The
best workers get their tools to do the work for them. -- Syndicate Wars

The pickaxe is pretty comprehensive and has good examples IMHO.

Cheers

  robert

···

On 15.08.2007 06:46, Roger Pack wrote:

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

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

robert

···

2007/8/21, Roger Pack <rogerpack2005@gmail.com>:

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

Thanks!
Robert Klemme wrote:

···

2007/8/21, Roger Pack <rogerpack2005@gmail.com>:

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

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