Recently Iv'e been trying to program a simple TCP server to later build into a chat room. But every time I launch the server (server.rb), and then I try to use the client (client.rb) I get this error:
Sam#ANDERSAMERPC C:\Users\Sam\Documents\Coding
> client.rb
C:/Users/Sam/Documents/Coding/client.rb:6:in `initialize': No connection could be made because the target machine actively refused it. - connect(2) for "localhost" port 2001 (Errno::ECONNREFUSED)
from C:/Users/Sam/Documents/Coding/client.rb:6:in `open'
from C:/Users/Sam/Documents/Coding/client.rb:6:in `<main>'
I am using CMD to run this and I've tried turning off firewall briefly.
Here is the code for both of the programs...
This is server.rb
require 'socket'
server = TCPServer.open(2000) # Socket to listen on port 2000
loop {
Thread.start(server.accept) do |client|
client.puts(Time.now.ctime) # Send time to the client
client.puts "Closing connection. Bye!"
client.close
end
}
Here's client.rb:
require 'socket'
hostname = "localhost"
port = 2000
s = TCPSocket.open(hostname, port)
while line = s.gets # Reads lines from socket
puts line.chop # And print with platform line terminator
end
s.close # Close socket when done
(This code is from http://www.tutorialspoint.com/ruby/ruby_socket_programming.htm just so you know.)
I guess there are 2 options:
Run your server.rb before client.rb.
Are you sure those are the exact same files that you are running. Because the error message says it can not connect to port 2001, whereas in both of your files they refer to 2000. Is it possible that you are editing and running different files? You will be surprised, how common this is here on SO :)
Related
I'm trying to use the library HTTParty, but whenever I run the code below I receive an error.
Code:
require 'httparty'
response = HTTParty.get('http://example.com')
When I run the code I receive the error: Errno::ECONNREFUSED (Failed to open TCP connection to :80 (Connection refused - connect(2) for nil port 80)).
I don't get any error when I run the same code in net/http. I don't know if this helps, but the system I'm running is Linux Mint 18.3 Cinnamon 64-bit .
I know that this is late, but using https://example.com instead of http://example.com was the solution to my problem.
I'am learning ruby socket programming and I'am on linux OS(Ubuntu 16.04 to be exact).
The following code:
require 'socket'
socket = TCPSocket.new('0.0.0.0', 8080)
client = socket.accept
puts "New client! #{client}"
client.write("Hello from server")
client.close
is giving me the following error:
sock2.rb:3:in initialize': Connection refused - connect(2) for "0.0.0.0" port 8080 (Errno::ECONNREFUSED)
from sock2.rb:3:innew'
from sock2.rb:3:in `'
Should I use a different IP and port? or do I have to make some sort of configuration on my unix system for the client and server to speak to each other.
TCPSocket.new tries to connect to the host specified in the arguments. It looks like you are trying to set up a server listening on that port, for that you should use TCPServer instead:
socket = TCPServer.new('0.0.0.0', 8080)
You can then connect to this server with another client. That client could possibly use TCPSocket.
I'm trying to catch all *.dev requests on port 80 and send them to the right Rack project by using Rack Proxy. I'm able to catch the requests and based on the URI I'll look for a config.ru in a specific folder. When I'm able to find one I'll boot up the server on port 3000.
After that, whenever I recieve a request on port 80, I try to set the HTTP_HOST to localhost:3000, but I'm getting the message Unexpected error while processing request: Connection refused - connect(2) for "localhost" port 3000. I am able to access the application through localhost:3000, but not through a *.dev domain. I already tried using different ports, but that's not working either, so I guess it has something to do with the user that's running it. However, I hope someone can help me with this.
require 'rack-proxy'
class AppProxy < Rack::Proxy
def rewrite_env(env)
request = Rack::Request.new(env)
site = request.host[0..-5]
uid = File.stat(__FILE__).uid
path = Etc.getpwuid(uid).dir + '/Software/Applications/'
front_controller = "#{path}#{site}/config.ru"
if File.file?(front_controller)
system "rackup -p 3000 -D #{front_controller} "
env["HTTP_HOST"] = "localhost:3000"
else
raise Exception.new "Not found"
end
env
end
end
run AppProxy.new
EDIT: I've checked if there is something listening on port 3000. After running the server and sudo lsof -i -n -P | grep TCP I get the following result for the ports 80 and 3000:
ruby 56247 root 10u IPv4 0x727d74bd0b95bd9b 0t0 TCP *:80 (LISTEN)
ruby 56247 root 11u IPv4 0x727d74bd0a3b9bfb 0t0 TCP 127.0.0.1:80->127.0.0.1:52773 (ESTABLISHED)
ruby 56255 root 12u IPv6 0x727d74bd094e3c8b 0t0 TCP [::1]:3000 (LISTEN)
I'm not sure if this is any useful because I don't know the exact meaning of this.
Solved it. The problem was that booting up the server was a bit slower then setting the HTTP_HOST to a different location and port 3000 was not in use yet. Waiting for a second solved the problem. My code looks like this now:
require 'rack-proxy'
class AppProxy < Rack::Proxy
def rewrite_env(env)
request = Rack::Request.new(env)
site = request.host[0..-5]
uid = File.stat(__FILE__).uid
path = Etc.getpwuid(uid).dir + '/Software/Applications/'
front_controller = "#{path}#{site}/config.ru"
if File.file?(front_controller)
system "rackup -D -p 3000 #{front_controller} "
sleep(1)
env["HTTP_HOST"] = "localhost:3000"
else
raise Exception.new "Not found"
end
env
end
end
run AppProxy.new
I created a TCPServer with ruby gserver.
Everytime I connect remotly to the server, it takes 2-4 seconds until connection is established.
This is only happen if I connect from remote machine.
Connection from same machine has running the service will send immidiate response.
For the connection on same machine there is no difference if I connect via localhost or via the machines ip.
I think delay depends on reverse lookup but can not localize why.
in gserver.rb it is line 263
client = #tcpServer.accept
Here the delay occurs, I do not know what is in this method.
I added all machines which are used during tests to the local hosts file. But that changed nothing.
Same happens when using Webrick, I tried to set also
BasicSocket.do_not_reverse_lookup = true
as well as direct on the resulting server socket
Socket.do_not_reverse_lookup = true
as well as on client connection socket
client.do_not_reverse_lookup = true
But that also changed nothing on delay.
Whenever connection is established, the values of remote_host and remote_ip are resolved and as defined in hosts file.
I tried that running ruby 2.2.1 on ubuntu 14.04 as well as ruby 1.9.3 running debian wheezy.
Same behavior - (long) delay on connecting service.
Q: How to fix that / disable lookup on TCPServer?
The problem depends on my client machine where I run on MAC OSX Mav.
The used telnet client tries to open IPv6 connection and afterwards IPv4.
To solve the delay, just open connection with
telnet -4 my-server 3333
I have build a small connect echo servive where you can check resolves and timings.
If you change NO_REVERSE_LOOKUP you will get IPs or ADDRESSes and if not resolveable, different response times.
require 'socket'
NO_REVERSE_LOOKUP = true
CONNECT_PORT = 3333
puts "#{Time.now} Starting service on port: #{CONNECT_PORT}"
# the full hell - just to test if anything meets what we want
TCPServer.do_not_reverse_lookup = NO_REVERSE_LOOKUP
BasicSocket.do_not_reverse_lookup = NO_REVERSE_LOOKUP
Socket.do_not_reverse_lookup = NO_REVERSE_LOOKUP
srv = TCPServer.open(CONNECT_PORT)
puts "#{Time.now} Waiting for client"
client = srv.accept
puts "#{Time.now} Client connected"
client.do_not_reverse_lookup = NO_REVERSE_LOOKUP
client.print "Hello connected\n"
# in case that we disabled reverse lookup, we should only receive IP Adresses
puts "#{Time.now} Getting server address infos"
puts "SERVER INFO:"
puts NO_REVERSE_LOOKUP ? client.addr(:numeric) : client.addr(:hostname)
puts ""
puts "#{Time.now} Getting remote client infos"
puts "REMOTE INFO:"
puts NO_REVERSE_LOOKUP ? client.peeraddr(:numeric) : client.peeraddr(:hostname)
###
puts "#{Time.now} Closing connection"
client.close
puts "#{Time.now} End"
Thanks to drbrain from #ruby-lang irc for pointing me to the IPv6 problem.
Can't make TCPSocket connect to TCPServer:
Client
require 'socket'
require 'io/console'
TCPSocket.open('127.0.0.1', '2000') { |socket|
#socket.puts('abcdefghijklmn')
puts socket.read
}
Server
require 'socket' # Get sockets from stdlib
server = TCPServer.open(2000) # Socket to listen on port 2000
loop { # Servers run forever
Thread.start(server.accept) do |client|
client.puts(Time.now.ctime) # Send the time to the client
client.puts "Closing the connection. Bye!"
client.close # Disconnect from the client
end
}
Error:
send_socket.rb:4:in `initialize': No connection could be made because the target machine actively refused it. - connect(2) (Errno::ECONNREFUSED)
from send_socket.rb:4:in `open'
from send_socket.rb:4:in `<main>'
When connecting to port 80 where IIS is listeninig, TCPSocket works fine, so I suppose there is something wrong with TCPServer example.
Switching the firewall off doesn't help. Moreover - when I stop IIS and set TCPServer to port 80 error is the same.