#ruby #sockets #tcpserver #reverse-lookup
#ruby #сокеты #tcpserver #обратный поиск
Вопрос:
Я создал TCPServer с ruby gserver.
Каждый раз, когда я удаленно подключаюсь к серверу, требуется 2-4 секунды, пока соединение не будет установлено.
Это происходит только при подключении с удаленного компьютера.
Соединение с того же компьютера, на котором запущена служба, отправит немедленный ответ.
Для соединения на том же компьютере нет разницы, подключаюсь ли я через localhost или через IP-адрес компьютера.
Я думаю, что задержка зависит от обратного поиска, но не могу определить, почему.
в gserver.rb это строка 263
client = @tcpServer.accept
Здесь возникает задержка, я не знаю, что в этом методе.
Я добавил все машины, которые используются во время тестов, в локальный файл hosts. Но это ничего не изменило.
То же самое происходит при использовании Webrick, я попытался установить также
BasicSocket.do_not_reverse_lookup = true
а также прямой доступ к результирующему сокету сервера
Socket.do_not_reverse_lookup = true
а также в сокете клиентского подключения
client.do_not_reverse_lookup = true
Но это также ничего не изменило в отношении задержки.
Всякий раз, когда устанавливается соединение, значения remote_host и remote_ip разрешаются и определяются в файле hosts.
Я попробовал запустить ruby 2.2.1 на ubuntu 14.04, а также ruby 1.9.3 под управлением debian wheezy.
То же поведение — (длительная) задержка при подключении службы.
Вопрос: Как это исправить / отключить поиск на TCPServer?
Комментарии:
1. Я провел тот же тест с webrick — то же поведение, при подключении с пульта дистанционного управления задержка составляет 2-4 секунды.
2. Я также настроил свои системы nsswitch.conf один раз, чтобы использовать только файлы, но опять никакого эффекта — все равно задержка
Ответ №1:
Проблема зависит от моего клиентского компьютера, на котором я запускаю MAC OSX Mav.
Используемый клиент telnet пытается открыть соединение IPv6, а затем IPv4.
Чтобы устранить задержку, просто откройте соединение с
telnet -4 my-server 3333
Я создал небольшой эхо-сервер connect, где вы можете проверять разрешения и тайминги.
Если вы измените NO_REVERSE_LOOKUP, вы получите IP-адреса или адреса, а если это невозможно, разное время отклика.
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 connectedn"
# 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"
Спасибо drbrain из #ruby-lang irc за указание мне на проблему IPv6.