Search code examples
rubyservertelnet

Ruby Telnet refuses connection


I need to make a cache server, one like memcached actually, so I´m trying to start a Telnet server so I can send commands which will then tell me if i need to store data or read from a key. I thought of doing it this way since I need to implement a TCP server and I need to use commands so a normal HTTP server wouldn't be enough (though I could post the data and the address could be the command, I'm still figuring it out).

Now after that background, the real problem is that I can't even start my Telnet server, this is the code I found on the web:

localhost = Net::Telnet::new("Host" => "localhost",
                         "Timeout" => 10,
                         "Prompt" => /[$%#>] \z/n)
localhost.login("username", "password") { |c| print c }
localhost.cmd("command") { |c| print c }
localhost.close

I don't really understand much of this, maybe I'm trying to connect to and existing Telnet server with that code and that's why it's not working. Anyway the error I'm getting it's this:

C:/Ruby22-x64/lib/ruby/2.2.0/net/telnet.rb:350:in `initialize': No connection could be made because the target machine actively refused it. - connect(2) for "localhost" port 23 (Errno::ECONNREFUSED)
from C:/Ruby22-x64/lib/ruby/2.2.0/net/telnet.rb:350:in `open'
from C:/Ruby22-x64/lib/ruby/2.2.0/net/telnet.rb:350:in `block in initialize'
from C:/Ruby22-x64/lib/ruby/2.2.0/timeout.rb:88:in `block in timeout'
from C:/Ruby22-x64/lib/ruby/2.2.0/timeout.rb:98:in `call'
from C:/Ruby22-x64/lib/ruby/2.2.0/timeout.rb:98:in `timeout'
from C:/Ruby22-x64/lib/ruby/2.2.0/net/telnet.rb:349:in `initialize'
from C:/Users/Bruno/RubymineProjects/Ruby Server/Server.rb:37:in `new'
from C:/Users/Bruno/RubymineProjects/Ruby Server/Server.rb:37:in `<top (required)>'
from -e:1:in `load'
from -e:1:in `<main>'

Process finished with exit code 1

Thank you in advance for any help or tip, as I said I'm still trying to figure out how to do this.


Solution

  • What you probably want is this:

    localhost = Net::Telnet::new(
      "Host" => "localhost",
      "Port" => 8899,
      "Timeout" => 10,
      "Prompt" => /[$%#>] \z/n
    )
    

    That will connect to port 8899 on your local machine. As noted the telnet protocol is all but dead and really has no use in 2016.

    The telnet client on the other hand is great for connecting to TCP services with a plain-text protocol. This includes HTTP and, as you've observed, Memcache.

    I'd recommend using the more generic TCPServer as the basis for your code:

    server = TCPServer.new(8899)
    

    Then you can build up your service from there using threads, or if necessary, fibers.

    While telnet might be dead, TCP/IP is alive and well. Simple, plain-text protocols are as popular as ever, which is why it's easy to confuse telnet the protocol with telnet the tool.