lib/dnssd/reply.rb in dnssd-1.1.0 vs lib/dnssd/reply.rb in dnssd-1.2
- old
+ new
@@ -27,11 +27,11 @@
# The port for this service
attr_reader :port
##
- # The service associated with the reply, see DNSSD::Service
+ # The DNSSD::Service associated with the reply
attr_reader :service
##
# The hostname of the host provide the service
@@ -46,39 +46,108 @@
##
# The service type
attr_reader :type
+ ##
+ # Creates a DNSSD::Reply from +service+ and +flags+
+
def self.from_service(service, flags)
reply = new
reply.instance_variable_set :@service, service
reply.instance_variable_set :@flags, DNSSD::Flags.new(flags)
reply
end
##
+ # Connects to this Reply. If +target+ and +port+ are missing, DNSSD.resolve
+ # is automatically called. +family+ can be used to select a particular
+ # address family.
+
+ def connect(family = Socket::AF_UNSPEC)
+ unless target and port then
+ value = nil
+
+ DNSSD.resolve! self do |reply|
+ value = reply
+ break
+ end
+
+ return value.connect
+ end
+
+ socktype = case protocol
+ when 'tcp' then Socket::SOCK_STREAM
+ when 'udp' then Socket::SOCK_DGRAM
+ else raise ArgumentError, "invalid protocol #{protocol}"
+ end
+
+ addresses = Socket.getaddrinfo target, port, family, socktype
+
+ socket = nil
+
+ addresses.each do |address|
+ begin
+ case protocol
+ when 'tcp' then
+ socket = TCPSocket.new address[3], port
+ when 'udp' then
+ socket = UDPSocket.new
+ socket.connect address[3], port rescue next
+ end
+
+ return socket
+ rescue
+ next
+ end
+ end
+
+ raise DNSSD::Error, "unable to connect to #{target}:#{port}" unless socket
+ end
+
+ ##
# The full service domain name, see DNSS::Service#fullname
def fullname
DNSSD::Service.fullname @name.gsub("\032", ' '), @type, @domain
end
- def inspect
+ def inspect # :nodoc:
"#<%s:0x%x %p type: %s domain: %s interface: %s flags: %s>" % [
self.class, object_id, @name, @type, @domain, @interface, @flags
]
end
+ ##
+ # Protocol of this service
+
+ def protocol
+ type.split('.').last.sub '_', ''
+ end
+
+ ##
+ # Service name as in Socket.getservbyname
+
+ def service_name
+ type.split('.').first.sub '_', ''
+ end
+
+ ##
+ # Sets #name, #type and #domain from +fullname+
+
def set_fullname(fullname)
fullname = fullname.gsub(/\\([0-9]+)/) do $1.to_i.chr end
fullname = fullname.scan(/(?:[^\\.]|\\\.)+/).map do |part|
part.gsub "\\.", '.'
end
@name = fullname[0]
@type = fullname[1, 2].join '.'
@domain = fullname.last + '.'
end
+
+ ##
+ # Sets #name, #type and #domain
def set_names(name, type, domain)
set_fullname [name, type, domain].join('.')
end