Ruby socket does not get reply

Hi all,

I use a TCP connection and send some data like this:

begin
session = “mysession”
socket = TCPSocket.new(tcpaddress, port)
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
puts "sending to socket HELO " + session
socket.write ('HELO ’ + session)
puts socket.read
socket.close
rescue Exception => myException
puts “Exception rescued : #{myException}”
end

The socket never gets a reply, however telnet does:

$ telnet some_ip port
Trying some_ip…
Connected to some_ip
Escape character is ‘^]’.
HELO mysession
OK

As you can see the remote server replies “OK” as expected. What’s wrong?

Thanks in advanced!

PS: I have used puts and send methods also

I think you may want TCPServer, instead of TCPSocket

puts socket.read

This call (read) blocks until the other end of the connection closes it.
-r

Roger P. wrote in post #998583:

puts socket.read

This call (read) blocks until the other end of the connection closes it.
-r

Good one. From IO#read docs:

===
ios.read([length [, buffer]]) → string, buffer, or nil

If length is omitted or is nil, it reads until EOF…

And when the server closes the socket, ruby sends an EOF signal to the
other side.

This is the fix:

socket.write("HELO " + session + “\r\n”)

Thanks :smiley:

Robert Garrido wrote in post #998661:

This is the fix:

socket.write("HELO " + session + “\r\n”)

Thanks :smiley:

Just be aware that ruby is going to convert a “\n” to “\r\n” on windows,
so on windows you will actually be wrting:

“\r\n”
= “\r” + “\n”
= “\r” + “\r\n”
= “\r\r\n”

That may or may not make a difference to a particular program.

Robert Garrido wrote in post #998563:

As you can see the remote server replies “OK” as expected. What’s wrong?

If the server is expecting ‘line oriented input’, then the server will
continue trying to read from the socket until it encounters a newline,
i.e. you need to end the data you send with a newline.

When you use sockets, both sides have to communicate with an agreed upon
protocol. If one side deviates from that protocol, then you are going
to end up with deadlock, where both sides are waiting for the other side
to do something.

On May 14, 2011, at 1:16 PM, 7stud – wrote:

Just be aware that ruby is going to convert a “\n” to “\r\n” on windows,
so on windows you will actually be wrting:

“\r\n”
= “\r” + “\n”
= “\r” + “\r\n”
= “\r\r\n”

That may or may not make a difference to a particular program.

I don’t have a Windows system to test on but I’m pretty sure that
sockets are always automatically opened in binary mode. On my Mac OS
system:

irb> socket = TCPSocket.new(“www.google.com”, 80)
=> #<TCPSocket:fd 4>
irb > socket.binmode?
=> true

The HTTP protocol requires “\r\n” line endings though so they have to be
written explicitly on the binary socket as described in the earlier
messages.

Gary W.

7stud – wrote in post #998709:

That may or may not make a difference to a particular program.

One way to avoid the newline conversion is to use the actual ascii code
for a newline instead of “\n”:

“\r\n” in octal:

“\015\012”

“\r\n” in hex:

“\x0D\x0A”

To avoid having to put those ugly escape sequences in your string, the
perl socket library has the constant $CRLF, which can be used at the end
of strings when correct reading of the data requires that line endings
be marked with exactly one “\r” and one “\n”. However, I don’t think
ruby copied that feature from perl.