TCP/IP in Ruby

B

Brad

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
(e-mail address removed)
 
J

jjh-ruby-talk

BCoish> I've run into a problem that I'm hoping is not unique. I am
BCoish> learning TCP/IP programming in Ruby and the following code
BCoish> 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

BCoish> The preceeding code is used to run a server that accepts a
BCoish> single client. The client sends the server a string, the server
BCoish> reads and converts the string to uppercase and then sends it
BCoish> 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.

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

enjoy,

-jeremy
 
B

Brad

BCoish> I've run into a problem that I'm hoping is not unique. I am
BCoish> learning TCP/IP programming in Ruby and the following code
BCoish> 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

BCoish> The preceeding code is used to run a server that accepts a
BCoish> single client. The client sends the server a string, the server
BCoish> reads and converts the string to uppercase and then sends it
BCoish> 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.

BCoish> That's how it's supposed to work and on the PC it does work.
BCoish> However, on OpenVMS the client requires two, consecutive reads
BCoish> in order to get the uppercased value from the server (i.e. first
BCoish> read returns the original string "test"; second read returns the
BCoish> modified string sent back by the server "TEST"). This leads me
BCoish> to believe it's an internal buffer problem. Before I speculate
BCoish> further I wanted to ask if anyone has come across this before
BCoish> 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) :)

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. :)

Thanks,
Brad
 
J

jjh-ruby-talk

Sorry for taking so long to reply.

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

[...]

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

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

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

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

enjoy,

-jeremy
 
B

Brad

Sorry for taking so long to reply.

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

[...]

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

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

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

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. :) (But that doesn't mean I'm giving
up.)

Regards,
Brad
 

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

Staff online

Members online

Forum statistics

Threads
474,262
Messages
2,571,045
Members
48,769
Latest member
Clifft

Latest Threads

Top