Class: Addrinfo

Inherits:
Object
  • Object
show all
Defined in:
lib/socket.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.foreach(nodename, service, family = nil, socktype = nil, protocol = nil, flags = nil, &block) ⇒ Object

iterates over the list of Addrinfo objects obtained by Addrinfo.getaddrinfo.

Addrinfo.foreach(nil, 80) {|x| p x }
#=> #<Addrinfo: 127.0.0.1:80 TCP (:80)>
#   #<Addrinfo: 127.0.0.1:80 UDP (:80)>
#   #<Addrinfo: [::1]:80 TCP (:80)>
#   #<Addrinfo: [::1]:80 UDP (:80)>


162
163
164
# File 'lib/socket.rb', line 162

def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, &block)
  Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags).each(&block)
end

Instance Method Details

#bindObject

creates a socket bound to self.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.udp("0.0.0.0", 9981).bind {|s|
  s.local_address.connect {|s| s.send "hello", 0 }
  p s.recv(10) #=> "hello"
}


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/socket.rb', line 120

def bind
  sock = Socket.new(self.pfamily, self.socktype, self.protocol)
  begin
    sock.ipv6only! if self.ipv6?
    sock.setsockopt(:SOCKET, :REUSEADDR, 1)
    sock.bind(self)
    if block_given?
      yield sock
    else
      sock
    end
  ensure
    sock.close if !sock.closed? && (block_given? || $!)
  end
end

#connect(&block) ⇒ Object

creates a socket connected to the address of self.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.tcp("www.ruby-lang.org", 80).connect {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}


91
92
93
# File 'lib/socket.rb', line 91

def connect(&block)
  connect_internal(nil, &block)
end

#connect_from(*local_addr_args, &block) ⇒ Object

creates a socket connected to the address of self.

If one or more arguments given as local_addr_args, it is used as the local address of the socket. local_addr_args is given for family_addrinfo to obtain actual address.

If no arguments given, the local address of the socket is not bound.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.tcp("www.ruby-lang.org", 80).connect_from("0.0.0.0", 4649) {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}

# Addrinfo object can be taken for the argument.
Addrinfo.tcp("www.ruby-lang.org", 80).connect_from(Addrinfo.tcp("0.0.0.0", 4649)) {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}


77
78
79
# File 'lib/socket.rb', line 77

def connect_from(*local_addr_args, &block)
  connect_internal(family_addrinfo(*local_addr_args), &block)
end

#connect_to(*remote_addr_args, &block) ⇒ Object

creates a socket connected to remote_addr_args and bound to self.

If a block is given, it is called with the socket and the value of the block is returned. The socket is returned otherwise.

Addrinfo.tcp("0.0.0.0", 4649).connect_to("www.ruby-lang.org", 80) {|s|
  s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  puts s.read
}


105
106
107
108
# File 'lib/socket.rb', line 105

def connect_to(*remote_addr_args, &block)
  remote_addrinfo = family_addrinfo(*remote_addr_args)
  remote_addrinfo.send(:connect_internal, self, &block)
end

#family_addrinfo(*args) ⇒ Object

creates an Addrinfo object from the arguments.

The arguments are interpreted as similar to self.

Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("www.ruby-lang.org", 80)
#=> #<Addrinfo: 221.186.184.68:80 TCP (www.ruby-lang.org:80)>

Addrinfo.unix("/tmp/sock").family_addrinfo("/tmp/sock2")
#=> #<Addrinfo: /tmp/sock2 SOCK_STREAM>


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/socket.rb', line 14

def family_addrinfo(*args)
  if args.empty?
    raise ArgumentError, "no address specified"
  elsif Addrinfo === args.first
    raise ArgumentError, "too many arguments" if args.length != 1
  elsif self.ip?
    raise ArgumentError, "IP address needs host and port but #{args.length} arguments given" if args.length != 2
    host, port = args
    Addrinfo.getaddrinfo(host, port, self.pfamily, self.socktype, self.protocol)[0]
  elsif self.unix?
    raise ArgumentError, "UNIX socket needs single path argument but #{args.length} arguments given" if args.length != 1
    path, = args
    Addrinfo.unix(path)
  else
    raise ArgumentError, "unexpected family"
  end
end

#listen(backlog = 5) ⇒ Object

creates a listening socket bound to self.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/socket.rb', line 137

def listen(backlog=5)
  sock = Socket.new(self.pfamily, self.socktype, self.protocol)
  begin
    sock.ipv6only! if self.ipv6?
    sock.setsockopt(:SOCKET, :REUSEADDR, 1)
    sock.bind(self)
    sock.listen(backlog)
    if block_given?
      yield sock
    else
      sock
    end
  ensure
    sock.close if !sock.closed? && (block_given? || $!)
  end
end