PageRenderTime 61ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/ext/socket/lib/socket.rb

http://github.com/ruby/ruby
Ruby | 1357 lines | 491 code | 54 blank | 812 comment | 79 complexity | a6da0f058a4beccadac76ed70f102139 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0
  1. # frozen_string_literal: true
  2. require 'socket.so'
  3. require 'io/wait'
  4. class Addrinfo
  5. # creates an Addrinfo object from the arguments.
  6. #
  7. # The arguments are interpreted as similar to self.
  8. #
  9. # Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("www.ruby-lang.org", 80)
  10. # #=> #<Addrinfo: 221.186.184.68:80 TCP (www.ruby-lang.org:80)>
  11. #
  12. # Addrinfo.unix("/tmp/sock").family_addrinfo("/tmp/sock2")
  13. # #=> #<Addrinfo: /tmp/sock2 SOCK_STREAM>
  14. #
  15. def family_addrinfo(*args)
  16. if args.empty?
  17. raise ArgumentError, "no address specified"
  18. elsif Addrinfo === args.first
  19. raise ArgumentError, "too many arguments" if args.length != 1
  20. addrinfo = args.first
  21. if (self.pfamily != addrinfo.pfamily) ||
  22. (self.socktype != addrinfo.socktype)
  23. raise ArgumentError, "Addrinfo type mismatch"
  24. end
  25. addrinfo
  26. elsif self.ip?
  27. raise ArgumentError, "IP address needs host and port but #{args.length} arguments given" if args.length != 2
  28. host, port = args
  29. Addrinfo.getaddrinfo(host, port, self.pfamily, self.socktype, self.protocol)[0]
  30. elsif self.unix?
  31. raise ArgumentError, "UNIX socket needs single path argument but #{args.length} arguments given" if args.length != 1
  32. path, = args
  33. Addrinfo.unix(path)
  34. else
  35. raise ArgumentError, "unexpected family"
  36. end
  37. end
  38. # creates a new Socket connected to the address of +local_addrinfo+.
  39. #
  40. # If _local_addrinfo_ is nil, the address of the socket is not bound.
  41. #
  42. # The _timeout_ specify the seconds for timeout.
  43. # Errno::ETIMEDOUT is raised when timeout occur.
  44. #
  45. # If a block is given the created socket is yielded for each address.
  46. #
  47. def connect_internal(local_addrinfo, timeout=nil) # :yields: socket
  48. sock = Socket.new(self.pfamily, self.socktype, self.protocol)
  49. begin
  50. sock.ipv6only! if self.ipv6?
  51. sock.bind local_addrinfo if local_addrinfo
  52. if timeout
  53. case sock.connect_nonblock(self, exception: false)
  54. when 0 # success or EISCONN, other errors raise
  55. break
  56. when :wait_writable
  57. sock.wait_writable(timeout) or
  58. raise Errno::ETIMEDOUT, 'user specified timeout'
  59. end while true
  60. else
  61. sock.connect(self)
  62. end
  63. rescue Exception
  64. sock.close
  65. raise
  66. end
  67. if block_given?
  68. begin
  69. yield sock
  70. ensure
  71. sock.close
  72. end
  73. else
  74. sock
  75. end
  76. end
  77. protected :connect_internal
  78. # :call-seq:
  79. # addrinfo.connect_from([local_addr_args], [opts]) {|socket| ... }
  80. # addrinfo.connect_from([local_addr_args], [opts])
  81. #
  82. # creates a socket connected to the address of self.
  83. #
  84. # If one or more arguments given as _local_addr_args_,
  85. # it is used as the local address of the socket.
  86. # _local_addr_args_ is given for family_addrinfo to obtain actual address.
  87. #
  88. # If _local_addr_args_ is not given, the local address of the socket is not bound.
  89. #
  90. # The optional last argument _opts_ is options represented by a hash.
  91. # _opts_ may have following options:
  92. #
  93. # [:timeout] specify the timeout in seconds.
  94. #
  95. # If a block is given, it is called with the socket and the value of the block is returned.
  96. # The socket is returned otherwise.
  97. #
  98. # Addrinfo.tcp("www.ruby-lang.org", 80).connect_from("0.0.0.0", 4649) {|s|
  99. # s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  100. # puts s.read
  101. # }
  102. #
  103. # # Addrinfo object can be taken for the argument.
  104. # Addrinfo.tcp("www.ruby-lang.org", 80).connect_from(Addrinfo.tcp("0.0.0.0", 4649)) {|s|
  105. # s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  106. # puts s.read
  107. # }
  108. #
  109. def connect_from(*args, timeout: nil, &block)
  110. connect_internal(family_addrinfo(*args), timeout, &block)
  111. end
  112. # :call-seq:
  113. # addrinfo.connect([opts]) {|socket| ... }
  114. # addrinfo.connect([opts])
  115. #
  116. # creates a socket connected to the address of self.
  117. #
  118. # The optional argument _opts_ is options represented by a hash.
  119. # _opts_ may have following options:
  120. #
  121. # [:timeout] specify the timeout in seconds.
  122. #
  123. # If a block is given, it is called with the socket and the value of the block is returned.
  124. # The socket is returned otherwise.
  125. #
  126. # Addrinfo.tcp("www.ruby-lang.org", 80).connect {|s|
  127. # s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  128. # puts s.read
  129. # }
  130. #
  131. def connect(timeout: nil, &block)
  132. connect_internal(nil, timeout, &block)
  133. end
  134. # :call-seq:
  135. # addrinfo.connect_to([remote_addr_args], [opts]) {|socket| ... }
  136. # addrinfo.connect_to([remote_addr_args], [opts])
  137. #
  138. # creates a socket connected to _remote_addr_args_ and bound to self.
  139. #
  140. # The optional last argument _opts_ is options represented by a hash.
  141. # _opts_ may have following options:
  142. #
  143. # [:timeout] specify the timeout in seconds.
  144. #
  145. # If a block is given, it is called with the socket and the value of the block is returned.
  146. # The socket is returned otherwise.
  147. #
  148. # Addrinfo.tcp("0.0.0.0", 4649).connect_to("www.ruby-lang.org", 80) {|s|
  149. # s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  150. # puts s.read
  151. # }
  152. #
  153. def connect_to(*args, timeout: nil, &block)
  154. remote_addrinfo = family_addrinfo(*args)
  155. remote_addrinfo.connect_internal(self, timeout, &block)
  156. end
  157. # creates a socket bound to self.
  158. #
  159. # If a block is given, it is called with the socket and the value of the block is returned.
  160. # The socket is returned otherwise.
  161. #
  162. # Addrinfo.udp("0.0.0.0", 9981).bind {|s|
  163. # s.local_address.connect {|s| s.send "hello", 0 }
  164. # p s.recv(10) #=> "hello"
  165. # }
  166. #
  167. def bind
  168. sock = Socket.new(self.pfamily, self.socktype, self.protocol)
  169. begin
  170. sock.ipv6only! if self.ipv6?
  171. sock.setsockopt(:SOCKET, :REUSEADDR, 1)
  172. sock.bind(self)
  173. rescue Exception
  174. sock.close
  175. raise
  176. end
  177. if block_given?
  178. begin
  179. yield sock
  180. ensure
  181. sock.close
  182. end
  183. else
  184. sock
  185. end
  186. end
  187. # creates a listening socket bound to self.
  188. def listen(backlog=Socket::SOMAXCONN)
  189. sock = Socket.new(self.pfamily, self.socktype, self.protocol)
  190. begin
  191. sock.ipv6only! if self.ipv6?
  192. sock.setsockopt(:SOCKET, :REUSEADDR, 1)
  193. sock.bind(self)
  194. sock.listen(backlog)
  195. rescue Exception
  196. sock.close
  197. raise
  198. end
  199. if block_given?
  200. begin
  201. yield sock
  202. ensure
  203. sock.close
  204. end
  205. else
  206. sock
  207. end
  208. end
  209. # iterates over the list of Addrinfo objects obtained by Addrinfo.getaddrinfo.
  210. #
  211. # Addrinfo.foreach(nil, 80) {|x| p x }
  212. # #=> #<Addrinfo: 127.0.0.1:80 TCP (:80)>
  213. # # #<Addrinfo: 127.0.0.1:80 UDP (:80)>
  214. # # #<Addrinfo: [::1]:80 TCP (:80)>
  215. # # #<Addrinfo: [::1]:80 UDP (:80)>
  216. #
  217. def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, timeout: nil, &block)
  218. Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags, timeout: timeout).each(&block)
  219. end
  220. end
  221. class BasicSocket < IO
  222. # Returns an address of the socket suitable for connect in the local machine.
  223. #
  224. # This method returns _self_.local_address, except following condition.
  225. #
  226. # - IPv4 unspecified address (0.0.0.0) is replaced by IPv4 loopback address (127.0.0.1).
  227. # - IPv6 unspecified address (::) is replaced by IPv6 loopback address (::1).
  228. #
  229. # If the local address is not suitable for connect, SocketError is raised.
  230. # IPv4 and IPv6 address which port is 0 is not suitable for connect.
  231. # Unix domain socket which has no path is not suitable for connect.
  232. #
  233. # Addrinfo.tcp("0.0.0.0", 0).listen {|serv|
  234. # p serv.connect_address #=> #<Addrinfo: 127.0.0.1:53660 TCP>
  235. # serv.connect_address.connect {|c|
  236. # s, _ = serv.accept
  237. # p [c, s] #=> [#<Socket:fd 4>, #<Socket:fd 6>]
  238. # }
  239. # }
  240. #
  241. def connect_address
  242. addr = local_address
  243. afamily = addr.afamily
  244. if afamily == Socket::AF_INET
  245. raise SocketError, "unbound IPv4 socket" if addr.ip_port == 0
  246. if addr.ip_address == "0.0.0.0"
  247. addr = Addrinfo.new(["AF_INET", addr.ip_port, nil, "127.0.0.1"], addr.pfamily, addr.socktype, addr.protocol)
  248. end
  249. elsif defined?(Socket::AF_INET6) && afamily == Socket::AF_INET6
  250. raise SocketError, "unbound IPv6 socket" if addr.ip_port == 0
  251. if addr.ip_address == "::"
  252. addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol)
  253. elsif addr.ip_address == "0.0.0.0" # MacOS X 10.4 returns "a.b.c.d" for IPv4-mapped IPv6 address.
  254. addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol)
  255. elsif addr.ip_address == "::ffff:0.0.0.0" # MacOS X 10.6 returns "::ffff:a.b.c.d" for IPv4-mapped IPv6 address.
  256. addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol)
  257. end
  258. elsif defined?(Socket::AF_UNIX) && afamily == Socket::AF_UNIX
  259. raise SocketError, "unbound Unix socket" if addr.unix_path == ""
  260. end
  261. addr
  262. end
  263. # call-seq:
  264. # basicsocket.sendmsg(mesg, flags=0, dest_sockaddr=nil, *controls) => numbytes_sent
  265. #
  266. # sendmsg sends a message using sendmsg(2) system call in blocking manner.
  267. #
  268. # _mesg_ is a string to send.
  269. #
  270. # _flags_ is bitwise OR of MSG_* constants such as Socket::MSG_OOB.
  271. #
  272. # _dest_sockaddr_ is a destination socket address for connection-less socket.
  273. # It should be a sockaddr such as a result of Socket.sockaddr_in.
  274. # An Addrinfo object can be used too.
  275. #
  276. # _controls_ is a list of ancillary data.
  277. # The element of _controls_ should be Socket::AncillaryData or
  278. # 3-elements array.
  279. # The 3-element array should contains cmsg_level, cmsg_type and data.
  280. #
  281. # The return value, _numbytes_sent_ is an integer which is the number of bytes sent.
  282. #
  283. # sendmsg can be used to implement send_io as follows:
  284. #
  285. # # use Socket::AncillaryData.
  286. # ancdata = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, io.fileno)
  287. # sock.sendmsg("a", 0, nil, ancdata)
  288. #
  289. # # use 3-element array.
  290. # ancdata = [:SOCKET, :RIGHTS, [io.fileno].pack("i!")]
  291. # sock.sendmsg("\0", 0, nil, ancdata)
  292. def sendmsg(mesg, flags = 0, dest_sockaddr = nil, *controls)
  293. __sendmsg(mesg, flags, dest_sockaddr, controls)
  294. end
  295. # call-seq:
  296. # basicsocket.sendmsg_nonblock(mesg, flags=0, dest_sockaddr=nil, *controls, opts={}) => numbytes_sent
  297. #
  298. # sendmsg_nonblock sends a message using sendmsg(2) system call in non-blocking manner.
  299. #
  300. # It is similar to BasicSocket#sendmsg
  301. # but the non-blocking flag is set before the system call
  302. # and it doesn't retry the system call.
  303. #
  304. # By specifying a keyword argument _exception_ to +false+, you can indicate
  305. # that sendmsg_nonblock should not raise an IO::WaitWritable exception, but
  306. # return the symbol +:wait_writable+ instead.
  307. def sendmsg_nonblock(mesg, flags = 0, dest_sockaddr = nil, *controls,
  308. exception: true)
  309. __sendmsg_nonblock(mesg, flags, dest_sockaddr, controls, exception)
  310. end
  311. # call-seq:
  312. # basicsocket.recv_nonblock(maxlen [, flags [, buf [, options ]]]) => mesg
  313. #
  314. # Receives up to _maxlen_ bytes from +socket+ using recvfrom(2) after
  315. # O_NONBLOCK is set for the underlying file descriptor.
  316. # _flags_ is zero or more of the +MSG_+ options.
  317. # The result, _mesg_, is the data received.
  318. #
  319. # When recvfrom(2) returns 0, Socket#recv_nonblock returns
  320. # an empty string as data.
  321. # The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.
  322. #
  323. # === Parameters
  324. # * +maxlen+ - the number of bytes to receive from the socket
  325. # * +flags+ - zero or more of the +MSG_+ options
  326. # * +buf+ - destination String buffer
  327. # * +options+ - keyword hash, supporting `exception: false`
  328. #
  329. # === Example
  330. # serv = TCPServer.new("127.0.0.1", 0)
  331. # af, port, host, addr = serv.addr
  332. # c = TCPSocket.new(addr, port)
  333. # s = serv.accept
  334. # c.send "aaa", 0
  335. # begin # emulate blocking recv.
  336. # p s.recv_nonblock(10) #=> "aaa"
  337. # rescue IO::WaitReadable
  338. # IO.select([s])
  339. # retry
  340. # end
  341. #
  342. # Refer to Socket#recvfrom for the exceptions that may be thrown if the call
  343. # to _recv_nonblock_ fails.
  344. #
  345. # BasicSocket#recv_nonblock may raise any error corresponding to recvfrom(2) failure,
  346. # including Errno::EWOULDBLOCK.
  347. #
  348. # If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN,
  349. # it is extended by IO::WaitReadable.
  350. # So IO::WaitReadable can be used to rescue the exceptions for retrying recv_nonblock.
  351. #
  352. # By specifying a keyword argument _exception_ to +false+, you can indicate
  353. # that recv_nonblock should not raise an IO::WaitReadable exception, but
  354. # return the symbol +:wait_readable+ instead.
  355. #
  356. # === See
  357. # * Socket#recvfrom
  358. def recv_nonblock(len, flag = 0, str = nil, exception: true)
  359. __recv_nonblock(len, flag, str, exception)
  360. end
  361. # call-seq:
  362. # basicsocket.recvmsg(maxmesglen=nil, flags=0, maxcontrollen=nil, opts={}) => [mesg, sender_addrinfo, rflags, *controls]
  363. #
  364. # recvmsg receives a message using recvmsg(2) system call in blocking manner.
  365. #
  366. # _maxmesglen_ is the maximum length of mesg to receive.
  367. #
  368. # _flags_ is bitwise OR of MSG_* constants such as Socket::MSG_PEEK.
  369. #
  370. # _maxcontrollen_ is the maximum length of controls (ancillary data) to receive.
  371. #
  372. # _opts_ is option hash.
  373. # Currently :scm_rights=>bool is the only option.
  374. #
  375. # :scm_rights option specifies that application expects SCM_RIGHTS control message.
  376. # If the value is nil or false, application don't expects SCM_RIGHTS control message.
  377. # In this case, recvmsg closes the passed file descriptors immediately.
  378. # This is the default behavior.
  379. #
  380. # If :scm_rights value is neither nil nor false, application expects SCM_RIGHTS control message.
  381. # In this case, recvmsg creates IO objects for each file descriptors for
  382. # Socket::AncillaryData#unix_rights method.
  383. #
  384. # The return value is 4-elements array.
  385. #
  386. # _mesg_ is a string of the received message.
  387. #
  388. # _sender_addrinfo_ is a sender socket address for connection-less socket.
  389. # It is an Addrinfo object.
  390. # For connection-oriented socket such as TCP, sender_addrinfo is platform dependent.
  391. #
  392. # _rflags_ is a flags on the received message which is bitwise OR of MSG_* constants such as Socket::MSG_TRUNC.
  393. # It will be nil if the system uses 4.3BSD style old recvmsg system call.
  394. #
  395. # _controls_ is ancillary data which is an array of Socket::AncillaryData objects such as:
  396. #
  397. # #<Socket::AncillaryData: AF_UNIX SOCKET RIGHTS 7>
  398. #
  399. # _maxmesglen_ and _maxcontrollen_ can be nil.
  400. # In that case, the buffer will be grown until the message is not truncated.
  401. # Internally, MSG_PEEK is used.
  402. # Buffer full and MSG_CTRUNC are checked for truncation.
  403. #
  404. # recvmsg can be used to implement recv_io as follows:
  405. #
  406. # mesg, sender_sockaddr, rflags, *controls = sock.recvmsg(:scm_rights=>true)
  407. # controls.each {|ancdata|
  408. # if ancdata.cmsg_is?(:SOCKET, :RIGHTS)
  409. # return ancdata.unix_rights[0]
  410. # end
  411. # }
  412. def recvmsg(dlen = nil, flags = 0, clen = nil, scm_rights: false)
  413. __recvmsg(dlen, flags, clen, scm_rights)
  414. end
  415. # call-seq:
  416. # basicsocket.recvmsg_nonblock(maxdatalen=nil, flags=0, maxcontrollen=nil, opts={}) => [data, sender_addrinfo, rflags, *controls]
  417. #
  418. # recvmsg receives a message using recvmsg(2) system call in non-blocking manner.
  419. #
  420. # It is similar to BasicSocket#recvmsg
  421. # but non-blocking flag is set before the system call
  422. # and it doesn't retry the system call.
  423. #
  424. # By specifying a keyword argument _exception_ to +false+, you can indicate
  425. # that recvmsg_nonblock should not raise an IO::WaitReadable exception, but
  426. # return the symbol +:wait_readable+ instead.
  427. def recvmsg_nonblock(dlen = nil, flags = 0, clen = nil,
  428. scm_rights: false, exception: true)
  429. __recvmsg_nonblock(dlen, flags, clen, scm_rights, exception)
  430. end
  431. # Linux-specific optimizations to avoid fcntl for IO#read_nonblock
  432. # and IO#write_nonblock using MSG_DONTWAIT
  433. # Do other platforms support MSG_DONTWAIT reliably?
  434. if RUBY_PLATFORM =~ /linux/ && Socket.const_defined?(:MSG_DONTWAIT)
  435. def read_nonblock(len, str = nil, exception: true) # :nodoc:
  436. __read_nonblock(len, str, exception)
  437. end
  438. def write_nonblock(buf, exception: true) # :nodoc:
  439. __write_nonblock(buf, exception)
  440. end
  441. end
  442. end
  443. class Socket < BasicSocket
  444. # enable the socket option IPV6_V6ONLY if IPV6_V6ONLY is available.
  445. def ipv6only!
  446. if defined? Socket::IPV6_V6ONLY
  447. self.setsockopt(:IPV6, :V6ONLY, 1)
  448. end
  449. end
  450. # call-seq:
  451. # socket.recvfrom_nonblock(maxlen[, flags[, outbuf[, opts]]]) => [mesg, sender_addrinfo]
  452. #
  453. # Receives up to _maxlen_ bytes from +socket+ using recvfrom(2) after
  454. # O_NONBLOCK is set for the underlying file descriptor.
  455. # _flags_ is zero or more of the +MSG_+ options.
  456. # The first element of the results, _mesg_, is the data received.
  457. # The second element, _sender_addrinfo_, contains protocol-specific address
  458. # information of the sender.
  459. #
  460. # When recvfrom(2) returns 0, Socket#recvfrom_nonblock returns
  461. # an empty string as data.
  462. # The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.
  463. #
  464. # === Parameters
  465. # * +maxlen+ - the maximum number of bytes to receive from the socket
  466. # * +flags+ - zero or more of the +MSG_+ options
  467. # * +outbuf+ - destination String buffer
  468. # * +opts+ - keyword hash, supporting `exception: false`
  469. #
  470. # === Example
  471. # # In one file, start this first
  472. # require 'socket'
  473. # include Socket::Constants
  474. # socket = Socket.new(AF_INET, SOCK_STREAM, 0)
  475. # sockaddr = Socket.sockaddr_in(2200, 'localhost')
  476. # socket.bind(sockaddr)
  477. # socket.listen(5)
  478. # client, client_addrinfo = socket.accept
  479. # begin # emulate blocking recvfrom
  480. # pair = client.recvfrom_nonblock(20)
  481. # rescue IO::WaitReadable
  482. # IO.select([client])
  483. # retry
  484. # end
  485. # data = pair[0].chomp
  486. # puts "I only received 20 bytes '#{data}'"
  487. # sleep 1
  488. # socket.close
  489. #
  490. # # In another file, start this second
  491. # require 'socket'
  492. # include Socket::Constants
  493. # socket = Socket.new(AF_INET, SOCK_STREAM, 0)
  494. # sockaddr = Socket.sockaddr_in(2200, 'localhost')
  495. # socket.connect(sockaddr)
  496. # socket.puts "Watch this get cut short!"
  497. # socket.close
  498. #
  499. # Refer to Socket#recvfrom for the exceptions that may be thrown if the call
  500. # to _recvfrom_nonblock_ fails.
  501. #
  502. # Socket#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure,
  503. # including Errno::EWOULDBLOCK.
  504. #
  505. # If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN,
  506. # it is extended by IO::WaitReadable.
  507. # So IO::WaitReadable can be used to rescue the exceptions for retrying
  508. # recvfrom_nonblock.
  509. #
  510. # By specifying a keyword argument _exception_ to +false+, you can indicate
  511. # that recvfrom_nonblock should not raise an IO::WaitReadable exception, but
  512. # return the symbol +:wait_readable+ instead.
  513. #
  514. # === See
  515. # * Socket#recvfrom
  516. def recvfrom_nonblock(len, flag = 0, str = nil, exception: true)
  517. __recvfrom_nonblock(len, flag, str, exception)
  518. end
  519. # call-seq:
  520. # socket.accept_nonblock([options]) => [client_socket, client_addrinfo]
  521. #
  522. # Accepts an incoming connection using accept(2) after
  523. # O_NONBLOCK is set for the underlying file descriptor.
  524. # It returns an array containing the accepted socket
  525. # for the incoming connection, _client_socket_,
  526. # and an Addrinfo, _client_addrinfo_.
  527. #
  528. # === Example
  529. # # In one script, start this first
  530. # require 'socket'
  531. # include Socket::Constants
  532. # socket = Socket.new(AF_INET, SOCK_STREAM, 0)
  533. # sockaddr = Socket.sockaddr_in(2200, 'localhost')
  534. # socket.bind(sockaddr)
  535. # socket.listen(5)
  536. # begin # emulate blocking accept
  537. # client_socket, client_addrinfo = socket.accept_nonblock
  538. # rescue IO::WaitReadable, Errno::EINTR
  539. # IO.select([socket])
  540. # retry
  541. # end
  542. # puts "The client said, '#{client_socket.readline.chomp}'"
  543. # client_socket.puts "Hello from script one!"
  544. # socket.close
  545. #
  546. # # In another script, start this second
  547. # require 'socket'
  548. # include Socket::Constants
  549. # socket = Socket.new(AF_INET, SOCK_STREAM, 0)
  550. # sockaddr = Socket.sockaddr_in(2200, 'localhost')
  551. # socket.connect(sockaddr)
  552. # socket.puts "Hello from script 2."
  553. # puts "The server said, '#{socket.readline.chomp}'"
  554. # socket.close
  555. #
  556. # Refer to Socket#accept for the exceptions that may be thrown if the call
  557. # to _accept_nonblock_ fails.
  558. #
  559. # Socket#accept_nonblock may raise any error corresponding to accept(2) failure,
  560. # including Errno::EWOULDBLOCK.
  561. #
  562. # If the exception is Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::ECONNABORTED or Errno::EPROTO,
  563. # it is extended by IO::WaitReadable.
  564. # So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.
  565. #
  566. # By specifying a keyword argument _exception_ to +false+, you can indicate
  567. # that accept_nonblock should not raise an IO::WaitReadable exception, but
  568. # return the symbol +:wait_readable+ instead.
  569. #
  570. # === See
  571. # * Socket#accept
  572. def accept_nonblock(exception: true)
  573. __accept_nonblock(exception)
  574. end
  575. # :call-seq:
  576. # Socket.tcp(host, port, local_host=nil, local_port=nil, [opts]) {|socket| ... }
  577. # Socket.tcp(host, port, local_host=nil, local_port=nil, [opts])
  578. #
  579. # creates a new socket object connected to host:port using TCP/IP.
  580. #
  581. # If local_host:local_port is given,
  582. # the socket is bound to it.
  583. #
  584. # The optional last argument _opts_ is options represented by a hash.
  585. # _opts_ may have following options:
  586. #
  587. # [:connect_timeout] specify the timeout in seconds.
  588. # [:resolv_timeout] specify the name resolution timeout in seconds.
  589. #
  590. # If a block is given, the block is called with the socket.
  591. # The value of the block is returned.
  592. # The socket is closed when this method returns.
  593. #
  594. # If no block is given, the socket is returned.
  595. #
  596. # Socket.tcp("www.ruby-lang.org", 80) {|sock|
  597. # sock.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
  598. # sock.close_write
  599. # puts sock.read
  600. # }
  601. #
  602. def self.tcp(host, port, local_host = nil, local_port = nil, connect_timeout: nil, resolv_timeout: nil) # :yield: socket
  603. last_error = nil
  604. ret = nil
  605. local_addr_list = nil
  606. if local_host != nil || local_port != nil
  607. local_addr_list = Addrinfo.getaddrinfo(local_host, local_port, nil, :STREAM, nil)
  608. end
  609. Addrinfo.foreach(host, port, nil, :STREAM, timeout: resolv_timeout) {|ai|
  610. if local_addr_list
  611. local_addr = local_addr_list.find {|local_ai| local_ai.afamily == ai.afamily }
  612. next unless local_addr
  613. else
  614. local_addr = nil
  615. end
  616. begin
  617. sock = local_addr ?
  618. ai.connect_from(local_addr, timeout: connect_timeout) :
  619. ai.connect(timeout: connect_timeout)
  620. rescue SystemCallError
  621. last_error = $!
  622. next
  623. end
  624. ret = sock
  625. break
  626. }
  627. unless ret
  628. if last_error
  629. raise last_error
  630. else
  631. raise SocketError, "no appropriate local address"
  632. end
  633. end
  634. if block_given?
  635. begin
  636. yield ret
  637. ensure
  638. ret.close
  639. end
  640. else
  641. ret
  642. end
  643. end
  644. # :stopdoc:
  645. def self.ip_sockets_port0(ai_list, reuseaddr)
  646. sockets = []
  647. begin
  648. sockets.clear
  649. port = nil
  650. ai_list.each {|ai|
  651. begin
  652. s = Socket.new(ai.pfamily, ai.socktype, ai.protocol)
  653. rescue SystemCallError
  654. next
  655. end
  656. sockets << s
  657. s.ipv6only! if ai.ipv6?
  658. if reuseaddr
  659. s.setsockopt(:SOCKET, :REUSEADDR, 1)
  660. end
  661. unless port
  662. s.bind(ai)
  663. port = s.local_address.ip_port
  664. else
  665. s.bind(ai.family_addrinfo(ai.ip_address, port))
  666. end
  667. }
  668. rescue Errno::EADDRINUSE
  669. sockets.each(&:close)
  670. retry
  671. rescue Exception
  672. sockets.each(&:close)
  673. raise
  674. end
  675. sockets
  676. end
  677. class << self
  678. private :ip_sockets_port0
  679. end
  680. def self.tcp_server_sockets_port0(host)
  681. ai_list = Addrinfo.getaddrinfo(host, 0, nil, :STREAM, nil, Socket::AI_PASSIVE)
  682. sockets = ip_sockets_port0(ai_list, true)
  683. begin
  684. sockets.each {|s|
  685. s.listen(Socket::SOMAXCONN)
  686. }
  687. rescue Exception
  688. sockets.each(&:close)
  689. raise
  690. end
  691. sockets
  692. end
  693. class << self
  694. private :tcp_server_sockets_port0
  695. end
  696. # :startdoc:
  697. # creates TCP/IP server sockets for _host_ and _port_.
  698. # _host_ is optional.
  699. #
  700. # If no block given,
  701. # it returns an array of listening sockets.
  702. #
  703. # If a block is given, the block is called with the sockets.
  704. # The value of the block is returned.
  705. # The socket is closed when this method returns.
  706. #
  707. # If _port_ is 0, actual port number is chosen dynamically.
  708. # However all sockets in the result has same port number.
  709. #
  710. # # tcp_server_sockets returns two sockets.
  711. # sockets = Socket.tcp_server_sockets(1296)
  712. # p sockets #=> [#<Socket:fd 3>, #<Socket:fd 4>]
  713. #
  714. # # The sockets contains IPv6 and IPv4 sockets.
  715. # sockets.each {|s| p s.local_address }
  716. # #=> #<Addrinfo: [::]:1296 TCP>
  717. # # #<Addrinfo: 0.0.0.0:1296 TCP>
  718. #
  719. # # IPv6 and IPv4 socket has same port number, 53114, even if it is chosen dynamically.
  720. # sockets = Socket.tcp_server_sockets(0)
  721. # sockets.each {|s| p s.local_address }
  722. # #=> #<Addrinfo: [::]:53114 TCP>
  723. # # #<Addrinfo: 0.0.0.0:53114 TCP>
  724. #
  725. # # The block is called with the sockets.
  726. # Socket.tcp_server_sockets(0) {|sockets|
  727. # p sockets #=> [#<Socket:fd 3>, #<Socket:fd 4>]
  728. # }
  729. #
  730. def self.tcp_server_sockets(host=nil, port)
  731. if port == 0
  732. sockets = tcp_server_sockets_port0(host)
  733. else
  734. last_error = nil
  735. sockets = []
  736. begin
  737. Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai|
  738. begin
  739. s = ai.listen
  740. rescue SystemCallError
  741. last_error = $!
  742. next
  743. end
  744. sockets << s
  745. }
  746. if sockets.empty?
  747. raise last_error
  748. end
  749. rescue Exception
  750. sockets.each(&:close)
  751. raise
  752. end
  753. end
  754. if block_given?
  755. begin
  756. yield sockets
  757. ensure
  758. sockets.each(&:close)
  759. end
  760. else
  761. sockets
  762. end
  763. end
  764. # yield socket and client address for each a connection accepted via given sockets.
  765. #
  766. # The arguments are a list of sockets.
  767. # The individual argument should be a socket or an array of sockets.
  768. #
  769. # This method yields the block sequentially.
  770. # It means that the next connection is not accepted until the block returns.
  771. # So concurrent mechanism, thread for example, should be used to service multiple clients at a time.
  772. #
  773. def self.accept_loop(*sockets) # :yield: socket, client_addrinfo
  774. sockets.flatten!(1)
  775. if sockets.empty?
  776. raise ArgumentError, "no sockets"
  777. end
  778. loop {
  779. readable, _, _ = IO.select(sockets)
  780. readable.each {|r|
  781. sock, addr = r.accept_nonblock(exception: false)
  782. next if sock == :wait_readable
  783. yield sock, addr
  784. }
  785. }
  786. end
  787. # creates a TCP/IP server on _port_ and calls the block for each connection accepted.
  788. # The block is called with a socket and a client_address as an Addrinfo object.
  789. #
  790. # If _host_ is specified, it is used with _port_ to determine the server addresses.
  791. #
  792. # The socket is *not* closed when the block returns.
  793. # So application should close it explicitly.
  794. #
  795. # This method calls the block sequentially.
  796. # It means that the next connection is not accepted until the block returns.
  797. # So concurrent mechanism, thread for example, should be used to service multiple clients at a time.
  798. #
  799. # Note that Addrinfo.getaddrinfo is used to determine the server socket addresses.
  800. # When Addrinfo.getaddrinfo returns two or more addresses,
  801. # IPv4 and IPv6 address for example,
  802. # all of them are used.
  803. # Socket.tcp_server_loop succeeds if one socket can be used at least.
  804. #
  805. # # Sequential echo server.
  806. # # It services only one client at a time.
  807. # Socket.tcp_server_loop(16807) {|sock, client_addrinfo|
  808. # begin
  809. # IO.copy_stream(sock, sock)
  810. # ensure
  811. # sock.close
  812. # end
  813. # }
  814. #
  815. # # Threaded echo server
  816. # # It services multiple clients at a time.
  817. # # Note that it may accept connections too much.
  818. # Socket.tcp_server_loop(16807) {|sock, client_addrinfo|
  819. # Thread.new {
  820. # begin
  821. # IO.copy_stream(sock, sock)
  822. # ensure
  823. # sock.close
  824. # end
  825. # }
  826. # }
  827. #
  828. def self.tcp_server_loop(host=nil, port, &b) # :yield: socket, client_addrinfo
  829. tcp_server_sockets(host, port) {|sockets|
  830. accept_loop(sockets, &b)
  831. }
  832. end
  833. # :call-seq:
  834. # Socket.udp_server_sockets([host, ] port)
  835. #
  836. # Creates UDP/IP sockets for a UDP server.
  837. #
  838. # If no block given, it returns an array of sockets.
  839. #
  840. # If a block is given, the block is called with the sockets.
  841. # The value of the block is returned.
  842. # The sockets are closed when this method returns.
  843. #
  844. # If _port_ is zero, some port is chosen.
  845. # But the chosen port is used for the all sockets.
  846. #
  847. # # UDP/IP echo server
  848. # Socket.udp_server_sockets(0) {|sockets|
  849. # p sockets.first.local_address.ip_port #=> 32963
  850. # Socket.udp_server_loop_on(sockets) {|msg, msg_src|
  851. # msg_src.reply msg
  852. # }
  853. # }
  854. #
  855. def self.udp_server_sockets(host=nil, port)
  856. last_error = nil
  857. sockets = []
  858. ipv6_recvpktinfo = nil
  859. if defined? Socket::AncillaryData
  860. if defined? Socket::IPV6_RECVPKTINFO # RFC 3542
  861. ipv6_recvpktinfo = Socket::IPV6_RECVPKTINFO
  862. elsif defined? Socket::IPV6_PKTINFO # RFC 2292
  863. ipv6_recvpktinfo = Socket::IPV6_PKTINFO
  864. end
  865. end
  866. local_addrs = Socket.ip_address_list
  867. ip_list = []
  868. Addrinfo.foreach(host, port, nil, :DGRAM, nil, Socket::AI_PASSIVE) {|ai|
  869. if ai.ipv4? && ai.ip_address == "0.0.0.0"
  870. local_addrs.each {|a|
  871. next unless a.ipv4?
  872. ip_list << Addrinfo.new(a.to_sockaddr, :INET, :DGRAM, 0);
  873. }
  874. elsif ai.ipv6? && ai.ip_address == "::" && !ipv6_recvpktinfo
  875. local_addrs.each {|a|
  876. next unless a.ipv6?
  877. ip_list << Addrinfo.new(a.to_sockaddr, :INET6, :DGRAM, 0);
  878. }
  879. else
  880. ip_list << ai
  881. end
  882. }
  883. ip_list.uniq!(&:to_sockaddr)
  884. if port == 0
  885. sockets = ip_sockets_port0(ip_list, false)
  886. else
  887. ip_list.each {|ip|
  888. ai = Addrinfo.udp(ip.ip_address, port)
  889. begin
  890. s = ai.bind
  891. rescue SystemCallError
  892. last_error = $!
  893. next
  894. end
  895. sockets << s
  896. }
  897. if sockets.empty?
  898. raise last_error
  899. end
  900. end
  901. sockets.each {|s|
  902. ai = s.local_address
  903. if ipv6_recvpktinfo && ai.ipv6? && ai.ip_address == "::"
  904. s.setsockopt(:IPV6, ipv6_recvpktinfo, 1)
  905. end
  906. }
  907. if block_given?
  908. begin
  909. yield sockets
  910. ensure
  911. sockets.each(&:close) if sockets
  912. end
  913. else
  914. sockets
  915. end
  916. end
  917. # :call-seq:
  918. # Socket.udp_server_recv(sockets) {|msg, msg_src| ... }
  919. #
  920. # Receive UDP/IP packets from the given _sockets_.
  921. # For each packet received, the block is called.
  922. #
  923. # The block receives _msg_ and _msg_src_.
  924. # _msg_ is a string which is the payload of the received packet.
  925. # _msg_src_ is a Socket::UDPSource object which is used for reply.
  926. #
  927. # Socket.udp_server_loop can be implemented using this method as follows.
  928. #
  929. # udp_server_sockets(host, port) {|sockets|
  930. # loop {
  931. # readable, _, _ = IO.select(sockets)
  932. # udp_server_recv(readable) {|msg, msg_src| ... }
  933. # }
  934. # }
  935. #
  936. def self.udp_server_recv(sockets)
  937. sockets.each {|r|
  938. msg, sender_addrinfo, _, *controls = r.recvmsg_nonblock(exception: false)
  939. next if msg == :wait_readable
  940. ai = r.local_address
  941. if ai.ipv6? and pktinfo = controls.find {|c| c.cmsg_is?(:IPV6, :PKTINFO) }
  942. ai = Addrinfo.udp(pktinfo.ipv6_pktinfo_addr.ip_address, ai.ip_port)
  943. yield msg, UDPSource.new(sender_addrinfo, ai) {|reply_msg|
  944. r.sendmsg reply_msg, 0, sender_addrinfo, pktinfo
  945. }
  946. else
  947. yield msg, UDPSource.new(sender_addrinfo, ai) {|reply_msg|
  948. r.send reply_msg, 0, sender_addrinfo
  949. }
  950. end
  951. }
  952. end
  953. # :call-seq:
  954. # Socket.udp_server_loop_on(sockets) {|msg, msg_src| ... }
  955. #
  956. # Run UDP/IP server loop on the given sockets.
  957. #
  958. # The return value of Socket.udp_server_sockets is appropriate for the argument.
  959. #
  960. # It calls the block for each message received.
  961. #
  962. def self.udp_server_loop_on(sockets, &b) # :yield: msg, msg_src
  963. loop {
  964. readable, _, _ = IO.select(sockets)
  965. udp_server_recv(readable, &b)
  966. }
  967. end
  968. # :call-seq:
  969. # Socket.udp_server_loop(port) {|msg, msg_src| ... }
  970. # Socket.udp_server_loop(host, port) {|msg, msg_src| ... }
  971. #
  972. # creates a UDP/IP server on _port_ and calls the block for each message arrived.
  973. # The block is called with the message and its source information.
  974. #
  975. # This method allocates sockets internally using _port_.
  976. # If _host_ is specified, it is used conjunction with _port_ to determine the server addresses.
  977. #
  978. # The _msg_ is a string.
  979. #
  980. # The _msg_src_ is a Socket::UDPSource object.
  981. # It is used for reply.
  982. #
  983. # # UDP/IP echo server.
  984. # Socket.udp_server_loop(9261) {|msg, msg_src|
  985. # msg_src.reply msg
  986. # }
  987. #
  988. def self.udp_server_loop(host=nil, port, &b) # :yield: message, message_source
  989. udp_server_sockets(host, port) {|sockets|
  990. udp_server_loop_on(sockets, &b)
  991. }
  992. end
  993. # UDP/IP address information used by Socket.udp_server_loop.
  994. class UDPSource
  995. # +remote_address+ is an Addrinfo object.
  996. #
  997. # +local_address+ is an Addrinfo object.
  998. #
  999. # +reply_proc+ is a Proc used to send reply back to the source.
  1000. def initialize(remote_address, local_address, &reply_proc)
  1001. @remote_address = remote_address
  1002. @local_address = local_address
  1003. @reply_proc = reply_proc
  1004. end
  1005. # Address of the source
  1006. attr_reader :remote_address
  1007. # Local address
  1008. attr_reader :local_address
  1009. def inspect # :nodoc:
  1010. "\#<#{self.class}: #{@remote_address.inspect_sockaddr} to #{@local_address.inspect_sockaddr}>".dup
  1011. end
  1012. # Sends the String +msg+ to the source
  1013. def reply(msg)
  1014. @reply_proc.call msg
  1015. end
  1016. end
  1017. # creates a new socket connected to path using UNIX socket socket.
  1018. #
  1019. # If a block is given, the block is called with the socket.
  1020. # The value of the block is returned.
  1021. # The socket is closed when this method returns.
  1022. #
  1023. # If no block is given, the socket is returned.
  1024. #
  1025. # # talk to /tmp/sock socket.
  1026. # Socket.unix("/tmp/sock") {|sock|
  1027. # t = Thread.new { IO.copy_stream(sock, STDOUT) }
  1028. # IO.copy_stream(STDIN, sock)
  1029. # t.join
  1030. # }
  1031. #
  1032. def self.unix(path) # :yield: socket
  1033. addr = Addrinfo.unix(path)
  1034. sock = addr.connect
  1035. if block_given?
  1036. begin
  1037. yield sock
  1038. ensure
  1039. sock.close
  1040. end
  1041. else
  1042. sock
  1043. end
  1044. end
  1045. # creates a UNIX server socket on _path_
  1046. #
  1047. # If no block given, it returns a listening socket.
  1048. #
  1049. # If a block is given, it is called with the socket and the block value is returned.
  1050. # When the block exits, the socket is closed and the socket file is removed.
  1051. #
  1052. # socket = Socket.unix_server_socket("/tmp/s")
  1053. # p socket #=> #<Socket:fd 3>
  1054. # p socket.local_address #=> #<Addrinfo: /tmp/s SOCK_STREAM>
  1055. #
  1056. # Socket.unix_server_socket("/tmp/sock") {|s|
  1057. # p s #=> #<Socket:fd 3>
  1058. # p s.local_address #=> # #<Addrinfo: /tmp/sock SOCK_STREAM>
  1059. # }
  1060. #
  1061. def self.unix_server_socket(path)
  1062. unless unix_socket_abstract_name?(path)
  1063. begin
  1064. st = File.lstat(path)
  1065. rescue Errno::ENOENT
  1066. end
  1067. if st&.socket? && st.owned?
  1068. File.unlink path
  1069. end
  1070. end
  1071. s = Addrinfo.unix(path).listen
  1072. if block_given?
  1073. begin
  1074. yield s
  1075. ensure
  1076. s.close
  1077. unless unix_socket_abstract_name?(path)
  1078. File.unlink path
  1079. end
  1080. end
  1081. else
  1082. s
  1083. end
  1084. end
  1085. class << self
  1086. private
  1087. def unix_socket_abstract_name?(path)
  1088. /linux/ =~ RUBY_PLATFORM && /\A(\0|\z)/ =~ path
  1089. end
  1090. end
  1091. # creates a UNIX socket server on _path_.
  1092. # It calls the block for each socket accepted.
  1093. #
  1094. # If _host_ is specified, it is used with _port_ to determine the server ports.
  1095. #
  1096. # The socket is *not* closed when the block returns.
  1097. # So application should close it.
  1098. #
  1099. # This method deletes the socket file pointed by _path_ at first if
  1100. # the file is a socket file and it is owned by the user of the application.
  1101. # This is safe only if the directory of _path_ is not changed by a malicious user.
  1102. # So don't use /tmp/malicious-users-directory/socket.
  1103. # Note that /tmp/socket and /tmp/your-private-directory/socket is safe assuming that /tmp has sticky bit.
  1104. #
  1105. # # Sequential echo server.
  1106. # # It services only one client at a time.
  1107. # Socket.unix_server_loop("/tmp/sock") {|sock, client_addrinfo|
  1108. # begin
  1109. # IO.copy_stream(sock, sock)
  1110. # ensure
  1111. # sock.close
  1112. # end
  1113. # }
  1114. #
  1115. def self.unix_server_loop(path, &b) # :yield: socket, client_addrinfo
  1116. unix_server_socket(path) {|serv|
  1117. accept_loop(serv, &b)
  1118. }
  1119. end
  1120. # call-seq:
  1121. # socket.connect_nonblock(remote_sockaddr, [options]) => 0
  1122. #
  1123. # Requests a connection to be made on the given +remote_sockaddr+ after
  1124. # O_NONBLOCK is set for the underlying file descriptor.
  1125. # Returns 0 if successful, otherwise an exception is raised.
  1126. #
  1127. # === Parameter
  1128. # # +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object
  1129. #
  1130. # === Example:
  1131. # # Pull down Google's web page
  1132. # require 'socket'
  1133. # include Socket::Constants
  1134. # socket = Socket.new(AF_INET, SOCK_STREAM, 0)
  1135. # sockaddr = Socket.sockaddr_in(80, 'www.google.com')
  1136. # begin # emulate blocking connect
  1137. # socket.connect_nonblock(sockaddr)
  1138. # rescue IO::WaitWritable
  1139. # IO.select(nil, [socket]) # wait 3-way handshake completion
  1140. # begin
  1141. # socket.connect_nonblock(sockaddr) # check connection failure
  1142. # rescue Errno::EISCONN
  1143. # end
  1144. # end
  1145. # socket.write("GET / HTTP/1.0\r\n\r\n")
  1146. # results = socket.read
  1147. #
  1148. # Refer to Socket#connect for the exceptions that may be thrown if the call
  1149. # to _connect_nonblock_ fails.
  1150. #
  1151. # Socket#connect_nonblock may raise any error corresponding to connect(2) failure,
  1152. # including Errno::EINPROGRESS.
  1153. #
  1154. # If the exception is Errno::EINPROGRESS,
  1155. # it is extended by IO::WaitWritable.
  1156. # So IO::WaitWritable can be used to rescue the exceptions for retrying connect_nonblock.
  1157. #
  1158. # By specifying a keyword argument _exception_ to +false+, you can indicate
  1159. # that connect_nonblock should not raise an IO::WaitWritable exception, but
  1160. # return the symbol +:wait_writable+ instead.
  1161. #
  1162. # === See
  1163. # # Socket#connect
  1164. def connect_nonblock(addr, exception: true)
  1165. __connect_nonblock(addr, exception)
  1166. end
  1167. end
  1168. class UDPSocket < IPSocket
  1169. # call-seq:
  1170. # udpsocket.recvfrom_nonblock(maxlen [, flags[, outbuf [, options]]]) => [mesg, sender_inet_addr]
  1171. #
  1172. # Receives up to _maxlen_ bytes from +udpsocket+ using recvfrom(2) after
  1173. # O_NONBLOCK is set for the underlying file descriptor.
  1174. # _flags_ is zero or more of the +MSG_+ options.
  1175. # The first element of the results, _mesg_, is the data received.
  1176. # The second element, _sender_inet_addr_, is an array to represent the sender address.
  1177. #
  1178. # When recvfrom(2) returns 0,
  1179. # Socket#recvfrom_nonblock returns an empty string as data.
  1180. # It means an empty packet.
  1181. #
  1182. # === Parameters
  1183. # * +maxlen+ - the number of bytes to receive from the socket
  1184. # * +flags+ - zero or more of the +MSG_+ options
  1185. # * +outbuf+ - destination String buffer
  1186. # * +options+ - keyword hash, supporting `exception: false`
  1187. #
  1188. # === Example
  1189. # require 'socket'
  1190. # s1 = UDPSocket.new
  1191. # s1.bind("127.0.0.1", 0)
  1192. # s2 = UDPSocket.new
  1193. # s2.bind("127.0.0.1", 0)
  1194. # s2.connect(*s1.addr.values_at(3,1))
  1195. # s1.connect(*s2.addr.values_at(3,1))
  1196. # s1.send "aaa", 0
  1197. # begin # emulate blocking recvfrom
  1198. # p s2.recvfrom_nonblock(10) #=> ["aaa", ["AF_INET", 33302, "localhost.localdomain", "127.0.0.1"]]
  1199. # rescue IO::WaitReadable
  1200. # IO.select([s2])
  1201. # retry
  1202. # end
  1203. #
  1204. # Refer to Socket#recvfrom for the exceptions that may be thrown if the call
  1205. # to _recvfrom_nonblock_ fails.
  1206. #
  1207. # UDPSocket#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure,
  1208. # including Errno::EWOULDBLOCK.
  1209. #
  1210. # If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN,
  1211. # it is extended by IO::WaitReadable.
  1212. # So IO::WaitReadable can be used to rescue the exceptions for retrying recvfrom_nonblock.
  1213. #
  1214. # By specifying a keyword argument _exception_ to +false+, you can indicate
  1215. # that recvfrom_nonblock should not raise an IO::WaitReadable exception, but
  1216. # return the symbol +:wait_readable+ instead.
  1217. #
  1218. # === See
  1219. # * Socket#recvfrom
  1220. def recvfrom_nonblock(len, flag = 0, outbuf = nil, exception: true)
  1221. __recvfrom_nonblock(len, flag, outbuf, exception)
  1222. end
  1223. end
  1224. class TCPServer < TCPSocket
  1225. # call-seq:
  1226. # tcpserver.accept_nonblock([options]) => tcpsocket
  1227. #
  1228. # Accepts an incoming connection using accept(2) after
  1229. # O_NONBLOCK is set for the underlying file descriptor.
  1230. # It returns an accepted TCPSocket for the incoming connection.
  1231. #
  1232. # === Example
  1233. # require 'socket'
  1234. # serv = TCPServer.new(2202)
  1235. # begin # emulate blocking accept
  1236. # sock = serv.accept_nonblock
  1237. # rescue IO::WaitReadable, Errno::EINTR
  1238. # IO.select([serv])
  1239. # retry
  1240. # end
  1241. # # sock is an accepted socket.
  1242. #
  1243. # Refer to Socket#accept for the exceptions that may be thrown if the call
  1244. # to TCPServer#accept_nonblock fails.
  1245. #
  1246. # TCPServer#accept_nonblock may raise any error corresponding to accept(2) failure,
  1247. # including Errno::EWOULDBLOCK.
  1248. #
  1249. # If the exception is Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::ECONNABORTED, Errno::EPROTO,
  1250. # it is extended by IO::WaitReadable.
  1251. # So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.
  1252. #
  1253. # By specifying a keyword argument _exception_ to +false+, you can indicate
  1254. # that accept_nonblock should not raise an IO::WaitReadable exception, but
  1255. # return the symbol +:wait_readable+ instead.
  1256. #
  1257. # === See
  1258. # * TCPServer#accept
  1259. # * Socket#accept
  1260. def accept_nonblock(exception: true)
  1261. __accept_nonblock(exception)
  1262. end
  1263. end
  1264. class UNIXServer < UNIXSocket
  1265. # call-seq:
  1266. # unixserver.accept_nonblock([options]) => unixsocket
  1267. #
  1268. # Accepts an incoming connection using accept(2) after
  1269. # O_NONBLOCK is set for the underlying file descriptor.
  1270. # It returns an accepted UNIXSocket for the incoming connection.
  1271. #
  1272. # === Example
  1273. # require 'socket'
  1274. # serv = UNIXServer.new("/tmp/sock")
  1275. # begin # emulate blocking accept
  1276. # sock = serv.accept_nonblock
  1277. # rescue IO::WaitReadable, Errno::EINTR
  1278. # IO.select([serv])
  1279. # retry
  1280. # end
  1281. # # sock is an accepted socket.
  1282. #
  1283. # Refer to Socket#accept for the exceptions that may be thrown if the call
  1284. # to UNIXServer#accept_nonblock fails.
  1285. #
  1286. # UNIXServer#accept_nonblock may raise any error corresponding to accept(2) failure,
  1287. # including Errno::EWOULDBLOCK.
  1288. #
  1289. # If the exception is Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::ECONNABORTED or Errno::EPROTO,
  1290. # it is extended by IO::WaitReadable.
  1291. # So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.
  1292. #
  1293. # By specifying a keyword argument _exception_ to +false+, you can indicate
  1294. # that accept_nonblock should not raise an IO::WaitReadable exception, but
  1295. # return the symbol +:wait_readable+ instead.
  1296. #
  1297. # === See
  1298. # * UNIXServer#accept
  1299. # * Socket#accept
  1300. def accept_nonblock(exception: true)
  1301. __accept_nonblock(exception)
  1302. end
  1303. end if defined?(UNIXSocket)