Problems with Telnet

S

Sean Warburton

Firstly I'm a total newbie not just to Ruby but programming full stop so
go gentle, please :)

I'm looking for some help with a telnet problem. I am using a service
that uses telnet to let you check the registration status of a domain
name, you can only make so many requests per day so the maximum rate you
can send requests at is every 200ms. You also have to keep the
connection open as it takes 3 seconds to open a connection, each name
has to be followed by a carriage return and new line and finally the
final request needs to finish with #exit. The problem I have is this ...

I can open a connection no problem and if I send the following command

cmd("domain1.ca\r\ndomain2.ca\r\n#exit") {|str| print str}

I get the information I need returned for both domains but because I
need to wait 200ms between each domain, I need to actually send ...

cmd("domain1.ca\r\n"){|str| print str}
sleep 0.2
cmd("domain2.ca\r\n#exit"){|str| print str}

When I do that I get the correct information for the first domain then
it sits for a couple of seconds before returning a timed out error.

Can anyone point to what I'm doing wrong and also give me some pointers
on the best way to read and chomp the replies from the service.

TIA

Sean
 
S

Sean Warburton

Perhaps it will help if I post the actual error I receive ...

/usr/lib/ruby/1.8/net/telnet.rb:557:in `waitfor': timed out while
waiting for more data (Timeout::Error)
from /usr/lib/ruby/1.8/net/telnet.rb:692:in `cmd'
 
T

Toby Rodwell

Sean said:
Firstly I'm a total newbie not just to Ruby but programming full stop so
go gentle, please :)

I'm looking for some help with a telnet problem. I am using a service
that uses telnet to let you check the registration status of a domain
name, you can only make so many requests per day so the maximum rate you
can send requests at is every 200ms. You also have to keep the
connection open as it takes 3 seconds to open a connection, each name
has to be followed by a carriage return and new line and finally the
final request needs to finish with #exit. The problem I have is this ...

I can open a connection no problem and if I send the following command

cmd("domain1.ca\r\ndomain2.ca\r\n#exit") {|str| print str}

I get the information I need returned for both domains but because I
need to wait 200ms between each domain, I need to actually send ...

cmd("domain1.ca\r\n"){|str| print str}
sleep 0.2
cmd("domain2.ca\r\n#exit"){|str| print str}

When I do that I get the correct information for the first domain then
it sits for a couple of seconds before returning a timed out error.

Can anyone point to what I'm doing wrong and also give me some pointers
on the best way to read and chomp the replies from the service.

TIA

Sean

Do you *have* to wait 200ms between consecutive requests? If the 'sleep
0.2' is causing problems could you burst a group of requests, followed
by a longer pause, followed by another grouped request eg
cmd("domain1.ca\r\n...domain5.ca\r\n#exit") {|str| print str}
sleep 1
cmd("domain6.ca\r\n...domain10.ca\r\n#exit") {|str| print str}
etc

(It's all I can offer - like you I'm a network engineer not a
programmer!)
 
B

Brian Candler

Sean said:
I can open a connection no problem and if I send the following command

cmd("domain1.ca\r\ndomain2.ca\r\n#exit") {|str| print str}

I get the information I need returned for both domains but because I
need to wait 200ms between each domain, I need to actually send ...

cmd("domain1.ca\r\n"){|str| print str}
sleep 0.2
cmd("domain2.ca\r\n#exit"){|str| print str}

When I do that I get the correct information for the first domain then
it sits for a couple of seconds before returning a timed out error.

It's waiting for a "prompt". Having a look at the source code of
Net::Telnet to see what the default is, but you can override it, either
when you connect, or each time you sent a command:

cmd("String"=>"domain1.ca\r\n", "Match"=>/OK>/)

What you match depends entirely on how the server implements its
protocol of course, but basically you want to match whatever the
sequence of characters is that says "OK, I'm done, now send me another
command"

If it just sends you a one-line reply then maybe you just want to match
/\r\n/

This will give you a lock-step request-response. You may or may not need
the 200ms sleep (maybe the server always pauses 200ms before
responding?)

HTH,

Brian.
 
B

Brian Candler

Sean said:
Thanks Brian, that was it, it was waiting for a full stop!

Remember that "Match"=>/./ means "match any single character";
"Match"=>/\./ means "match a full stop"

Looking at /usr/lib/ruby/1.8/net/telnet.rb on my system, I see that the
default prompt is /[$%#>] \z/. That is, by default cmd() will collect
response characters until it sees one of those four characters followed
by a space and nothing else following (or until the far side
disconnects, which is what was happening when you stuffed 'exit' into
the command stream, or until a timeout occurs)

I haven't seen the protocol you're using, but maybe it isn't really
telnet, it's just a raw TCP socket. In that case you could use
TCPSocket.open(...) and the 'expect' library
(/usr/lib/ruby/1.8/expect.rb on my system) to wait for responses.
 

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

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top