TCP/IP in Ruby

All:

I’ve run into a problem that I’m hoping is not unique.
I am learning TCP/IP programming in Ruby and the
following code generates a strange result:

CLIENT.RB

=========

require 'socket’
s=TCPSocket.new(“localhost”, ARGV[0])
s.write(“test\n”)
puts s.gets

2nd read required to retrieve

modified string from server.

puts s.gets

s.close

SERVER.RB

=========

require "socket"
gs = TCPserver.open(0)
printf(“server is on port %d\n”, gs.addr[1])
s=gs.accept
puts s.gets
s.write(s.gets.upcase)
s.close

The preceeding code is used to run a server that accepts a
single client. The client sends the server a string, the
server reads and converts the string to uppercase and then
sends it back to the client.

That’s how it’s supposed to work and on the PC it does work.
However, on OpenVMS the client requires two, consecutive reads
in order to get the uppercased value from the server (i.e. first
read returns the original string “test”; second read returns the
modified string sent back by the server “TEST”). This leads me
to believe it’s an internal buffer problem. Before I speculate
further I wanted to ask if anyone has come across this before and
what may be the cause of it.

Regards,
Brad
BCoish@Dymaxion.com

I’ve run into a problem that I’m hoping is not unique. I am
learning TCP/IP programming in Ruby and the following code
generates a strange result:

The original code doesn’t work on a Linux machine either. Here’s
slightly altered code that probably will do what you want.

[jeremyhi@rapier ruby]$ cat client.rb

CLIENT.RB

=========

require ‘socket’
s=TCPSocket.new(“localhost”, ARGV[0])
s.write(“test\n”)
puts s.gets
s.close()
[jeremyhi@rapier ruby]$

Change server.rb to only read from the client 1 time.

[jeremyhi@rapier ruby]$ cat server.rb

SERVER.RB

=========

require “socket”
gs = TCPserver.open(0)
printf(“server is on port %d\n”, gs.addr[1])
s = gs.accept
line = s.gets
puts line
s.write(line.upcase)
s.close

The preceeding code is used to run a server that accepts a
single client. The client sends the server a string, the server
reads and converts the string to uppercase and then sends it
back to the client.

The server as originally written reads from the client twice, once for
each ‘gets’. Since the client is only writing once to the server this
is probably the underlying issue.

That’s how it’s supposed to work and on the PC it does work.
However, on OpenVMS the client requires two, consecutive reads
in order to get the uppercased value from the server (i.e. first
read returns the original string “test”; second read returns the
modified string sent back by the server “TEST”). This leads me
to believe it’s an internal buffer problem. Before I speculate
further I wanted to ask if anyone has come across this before
and what may be the cause of it.

enjoy,

-jeremy

jjh-ruby-talk@vieorhythms.com wrote in message news:87oeuzhr7h.fsf@planchet.hinegardner.org

I’ve run into a problem that I’m hoping is not unique. I am
learning TCP/IP programming in Ruby and the following code
generates a strange result:

The original code doesn’t work on a Linux machine either. Here’s
slightly altered code that probably will do what you want.

[jeremyhi@rapier ruby]$ cat client.rb

CLIENT.RB

=========

require ‘socket’
s=TCPSocket.new(“localhost”, ARGV[0])
s.write(“test\n”)
puts s.gets
s.close()
[jeremyhi@rapier ruby]$

Change server.rb to only read from the client 1 time.

[jeremyhi@rapier ruby]$ cat server.rb

SERVER.RB

=========

require “socket”
gs = TCPserver.open(0)
printf(“server is on port %d\n”, gs.addr[1])
s = gs.accept
line = s.gets
puts line
s.write(line.upcase)
s.close

The preceeding code is used to run a server that accepts a
single client. The client sends the server a string, the server
reads and converts the string to uppercase and then sends it
back to the client.

The server as originally written reads from the client twice, once for
each ‘gets’. Since the client is only writing once to the server this
is probably the underlying issue.

That’s how it’s supposed to work and on the PC it does work.
However, on OpenVMS the client requires two, consecutive reads
in order to get the uppercased value from the server (i.e. first
read returns the original string “test”; second read returns the
modified string sent back by the server “TEST”). This leads me
to believe it’s an internal buffer problem. Before I speculate
further I wanted to ask if anyone has come across this before
and what may be the cause of it.

enjoy,

-jeremy

First, thanks for the speedy response!
Second, I modified the source per your suggestions, but without success.
This is now the code I’m running:

Client

···

########
require ‘socket’
s=TCPSocket.new(“localhost”, ARGV[0])
s.write(“test\n”)
puts s.gets

puts s.gets

s.close

Server

########
require ‘socket’
gs = TCPServer.open(0)
printf(“server is on port %d\n”, gs.addr[1])
s=gs.accept
s.write(s.gets.upcase)
s.close

Even if I break s.gets.upcase down into it’s constituent parts
the problem persists. Any other ideas? (I’m fresh out) :slight_smile:

Perhaps something in the actual implimentation is the same everywhere else
except for OpenVMS. Hmm, wouldn’t be the first time, but it is a pain. :slight_smile:

Thanks,
Brad

Sorry for taking so long to reply.

First, thanks for the speedy response! Second, I modified the
source per your suggestions, but without success. This is now
the code I’m running:

[…]

Even if I break s.gets.upcase down into it’s constituent parts
the problem persists. Any other ideas? (I’m fresh out) :slight_smile:

Have you tried doing an explicit flush on the socket? So you would have
the following?

CLIENT.RB

=========

require ‘socket’
s=TCPSocket.new(“localhost”, ARGV[0])
s.write(“test\n”)
s.flush
puts s.gets
s.close()

SERVER.RB

=========

require “socket”
gs = TCPserver.open(0)
printf(“server is on port %d\n”, gs.addr[1])
s = gs.accept
line = s.gets
puts line
s.write(line.upcase)
s.flush
s.close

Perhaps something in the actual implimentation is the same
everywhere else except for OpenVMS. Hmm, wouldn’t be the first
time, but it is a pain. :slight_smile:

I don’t have access to an OpenVMS machine myself so I’m just throwing
out ideas here.

enjoy,

-jeremy

Jeremy:

Thanks for the reply! Unfortunately flushing the socket seems to have
had no effect. I think there is something internally, within the socket
implementation for OpenVMS, that is the problem. Something that I am
not yet familiar with. (like another post I made to the group regarding
threads: I had only to make an O/S specific define to make ruby threads
work on OpenVMS)

If I find the answer I’ll be sure to post it. And if you, or anyone
else has any further ideas I’m open to suggestions. I think I’ve
just about exhausted my resources. :slight_smile: (But that doesn’t mean I’m giving
up.)

Regards,
Brad

···

jjh-ruby-talk@vieorhythms.com wrote:

Sorry for taking so long to reply.

First, thanks for the speedy response! Second, I modified the
source per your suggestions, but without success. This is now
the code I’m running:

[…]

Even if I break s.gets.upcase down into it’s constituent parts
the problem persists. Any other ideas? (I’m fresh out) :slight_smile:

Have you tried doing an explicit flush on the socket? So you would have
the following?

CLIENT.RB

=========

require ‘socket’
s=TCPSocket.new(“localhost”, ARGV[0])
s.write(“test\n”)
s.flush
puts s.gets
s.close()

SERVER.RB

=========

require “socket”
gs = TCPserver.open(0)
printf(“server is on port %d\n”, gs.addr[1])
s = gs.accept
line = s.gets
puts line
s.write(line.upcase)
s.flush
s.close

Perhaps something in the actual implimentation is the same
everywhere else except for OpenVMS. Hmm, wouldn’t be the first
time, but it is a pain. :slight_smile:

I don’t have access to an OpenVMS machine myself so I’m just throwing
out ideas here.

enjoy,

-jeremy