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