This repository has been archived on 2021-09-15. You can view files and clone it, but cannot push or open issues or pull requests.
DUT2Curling/lib/net/udp.rb

120 lines
3.2 KiB
Ruby

require File.join(File.dirname(__FILE__), 'ping')
# The Net module serves as a namespace only.
module Net
# The Ping::UDP class encapsulates methods for UDP pings.
class Ping::UDP < Ping
@@service_check = true
# Returns whether or not the connect behavior should enforce remote
# service availability as well as reachability. The default is true.
#
def self.service_check
@@service_check
end
# Set whether or not the connect behavior should enforce remote
# service availability as well as reachability. If set to false
# then Errno::ECONNREFUSED or Errno::ECONNRESET will be considered
# a successful ping, meaning no actual data handshaking is required.
# By default, if either of those errors occurs it is considered a failed
# ping.
#
def self.service_check=(bool)
unless bool.kind_of?(TrueClass) || bool.kind_of?(FalseClass)
raise ArgumentError, 'argument must be true or false'
end
@@service_check = bool
end
# The maximum data size that can be sent in a UDP ping.
MAX_DATA = 64
# The data to send to the remote host. By default this is 'ping'.
# This should be MAX_DATA size characters or less.
#
attr_reader :data
# Creates and returns a new Ping::UDP object. This is effectively
# identical to its superclass constructor.
#
def initialize(host=nil, port=nil, timeout=5)
@data = 'ping'
super(host, port, timeout)
@bind_host = nil
@bind_port = nil
end
# Sets the data string sent to the remote host. This value cannot have
# a size greater than MAX_DATA.
#
def data=(string)
if string.size > MAX_DATA
err = "cannot set data string larger than #{MAX_DATA} characters"
raise ArgumentError, err
end
@data = string
end
# Associates the local end of the UDP connection with the given +host+
# and +port+. This is essentially a wrapper for UDPSocket#bind.
#
def bind(host, port)
@bind_host = host
@bind_port = port
end
# Sends a simple text string to the host and checks the return string. If
# the string sent and the string returned are a match then the ping was
# successful and true is returned. Otherwise, false is returned.
#
def ping(host = @host)
super(host)
bool = false
udp = UDPSocket.open
array = []
if @bind_host
udp.bind(@bind_host, @bind_port)
end
start_time = Time.now
begin
Timeout.timeout(@timeout){
udp.connect(host, @port)
udp.send(@data, 0)
array = udp.recvfrom(MAX_DATA)
}
rescue Errno::ECONNREFUSED, Errno::ECONNRESET => err
if @@service_check
@exception = err
else
bool = true
end
rescue Exception => err
@exception = err
else
if array[0] == @data
bool = true
end
ensure
udp.close if udp
end
# There is no duration if the ping failed
@duration = Time.now - start_time if bool
bool
end
alias ping? ping
alias pingecho ping
end
end