Class: NetworkUtils::Port
- Inherits:
-
Object
- Object
- NetworkUtils::Port
- Defined in:
- lib/network_utils/port.rb
Overview
Simple class to work with ports Allows to get random port number, check availability, etc.
Constant Summary collapse
- PORT_LOOKUP_RETRY_LIMIT =
The max limit for port lookup retries
50
- IANA_PORT_RANGE =
Internet Assigned Numbers Authority suggested range
(49_152..65_535).freeze
- SERVICES_FILE_PATH =
Current system’s IANA port assignments file Cound be changed using SERVICES_FILE_PATH ENV variable
'/etc/services'
Class Method Summary collapse
-
.available?(port, host = '127.0.0.1', timeout = 1) ⇒ Boolean
(also: free?)
Checks if the port is available (free) on the host.
-
.name(port) ⇒ Array
Checks the IANA port assignments file and returns possible service name.
-
.opened?(port, host = '127.0.0.1', timeout = 1) ⇒ Boolean
(also: occupied?)
Checks if the port is opened (occupied / being listened) on the host.
-
.random ⇒ Boolean
Generates random port from IANA recommended range.
-
.random_free ⇒ Boolean
Generates random port from IANA recommended range which is free on the localhost.
-
.service(port) ⇒ Array
Checks the IANA port assignments file for port info.
Class Method Details
.available?(port, host = '127.0.0.1', timeout = 1) ⇒ Boolean Also known as: free?
Checks if the port is available (free) on the host
39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/network_utils/port.rb', line 39 def self.available?(port, host = '127.0.0.1', timeout = 1) return false unless port && host && timeout && timeout.positive? Timeout.timeout(timeout) do TCPSocket.new(host, port).close false end rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH true rescue SocketError, Timeout::Error, Errno::EADDRNOTAVAIL false end |
.name(port) ⇒ Array
Just a convinience method over ::service
Checks the IANA port assignments file and returns possible service name
147 148 149 |
# File 'lib/network_utils/port.rb', line 147 def self.name(port) self.service(port).map { |s| s.fetch(:name) }.uniq end |
.opened?(port, host = '127.0.0.1', timeout = 1) ⇒ Boolean Also known as: occupied?
Just the opposite of ‘available?`
Checks if the port is opened (occupied / being listened) on the host
67 68 69 |
# File 'lib/network_utils/port.rb', line 67 def self.opened?(port, host = '127.0.0.1', timeout = 1) !available?(port, host, timeout) end |
.random ⇒ Boolean
The Internet Assigned Numbers Authority (IANA) suggests the range 49152 to 65535 (215+214 to 216−1) for dynamic or private ports.
Generates random port from IANA recommended range
78 79 80 |
# File 'lib/network_utils/port.rb', line 78 def self.random rand(IANA_PORT_RANGE) end |
.random_free ⇒ Boolean
The Internet Assigned Numbers Authority (IANA) suggests the range 49152 to 65535 (215+214 to 216−1) for dynamic or private ports.
Generates random port from IANA recommended range which is free on the localhost
89 90 91 92 93 94 95 96 |
# File 'lib/network_utils/port.rb', line 89 def self.random_free PORT_LOOKUP_RETRY_LIMIT.times do port = random return port if available?(port) end nil end |
.service(port) ⇒ Array
When looking just for a short name, use ::name
Checks the IANA port assignments file for port info
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/network_utils/port.rb', line 112 def self.service(port) # check the IANA port assignments file (default or custom) services_file = ENV['SERVICES_FILE_PATH'] || SERVICES_FILE_PATH return nil unless File.exist?(services_file) # read the file and extract info (ony lines matching "bacnet 47808/tcp # Building Automation and Control Networks" format) services = File.read(services_file).lines.map do |line| line_elements = line.split(/\s+/) next unless line_elements[1] =~ /\d+\// known_port, known_protocol = line_elements[1].split('/') { name: line_elements[0], port: known_port.to_i, protocol: known_protocol.to_sym, description: line_elements[3..-1]&.join(' ') } end # extract infor about the requested port Array.wrap(services.compact.find_all { |s| s[:port] == port }) end |