Upgrade to Pro — share decks privately, control downloads, hide ads and more …

たのしいSocketのしくみ / Socket Under a Microscope

たのしいSocketのしくみ / Socket Under a Microscope

More Decks by Misaki Shioi(塩井美咲/しおい)

Other Decks in Programming

Transcript

  1. QQTFMG ɹԘҪඒ࡙ ͓͍͠  ɹ஍Ҭ3VCZίϛϡχςΟ"TBLVTBSC ɹ3VCZίϛολʔ   ɹલ਎Πϕϯτ5PLZP(JSMTSC.FFUVQWPMʹొஃͯ͠·ͨ͠ !TIJPJNN

    (JU)VC !DPF@ FY5XJUUFS !DPF #MVFTLZ 3BDLϛυϧ΢ΣΞೖ໳ͷͨΊͷ3BDLϛυϧ΢ΣΞ IUUQTTQFBLFSEFDLDPNDPF@SBDLNJEPSVVFBSVNFOGBMTFUBNFGBMTFSBDLNJEPSVVFB
  2. αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial

    100 sock.write message ensure sock.close end αʔό 4PDLFUUDQ@TFSWFS@MPPQϝιου TPDLFUϥΠϒϥϦΛSFRVJSF
  3. αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial

    100 sock.write message ensure sock.close end αʔό ࣗ਎ͷϗετ໊MPDBMIPTU αʔόࣗ਎ͷϙʔτ൪߸
  4. αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial

    100 sock.write message ensure sock.close end αʔό αʔόͱͯ͠ߦ͏ॲཧ
  5. αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial

    100 sock.write message ensure sock.close end αʔό 4PDLFUΦϒδΣΫτ 4PDLFUΦϒδΣΫτ ιέοτΛ3VCZͷΦϒδΣΫτͰϥοϓ͠ɺ ɹ3VCZ͔Βѻ͑ΔΑ͏ʹͨ͠΋ͷ
  6. αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial

    100 sock.write message ensure sock.close end αʔό 4PDLFUΦϒδΣΫτ ͜͜ͰϒϩοΫม਺ʹ౉ͬͯ͘Δͷ͸ɺ ϦΫΤετΛૹ৴ͨ͠ΫϥΠΞϯτͱ ઀ଓࡁΈͷঢ়ଶͷ4PDLFUΦϒδΣΫτ
  7. αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial

    100 sock.write message ensure sock.close end αʔό 4PDLFUΦϒδΣΫτΛಡΈࠐΈ ΫϥΠΞϯτ͔ΒͷϦΫΤετϝοηʔδΛऔಘ ϦΫΤετΛૹ৴ͨ͠ΫϥΠΞϯτͱ ઀ଓࡁΈͷঢ়ଶͷ4PDLFUΦϒδΣΫτ
  8. αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial

    100 sock.write message ensure sock.close end αʔό 4PDLFUΦϒδΣΫτʹॻ͖ࠐΈ ΫϥΠΞϯτ΁ϨεϙϯεΛૹ৴ ͜͜Ͱ͸ϦΫΤετϝοηʔδΛ ͓͏Ήฦ͠ʹΫϥΠΞϯτʹૹ৴͍ͯ͠Δ ϦΫΤετΛૹ৴ͨ͠ΫϥΠΞϯτͱ ઀ଓࡁΈͷঢ়ଶͷ4PDLFUΦϒδΣΫτ
  9. αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial

    100 sock.write message ensure sock.close end αʔό Ұ௨ΓΫϥΠΞϯτʹର͢Δૢ࡞͕ऴΘͬͨΒ ઀ଓࡁΈ4PDLFUΦϒδΣΫτͷೖग़ྗΛΫϩʔζ ϦΫΤετΛૹ৴ͨ͠ΫϥΠΞϯτͱ ઀ଓࡁΈͷঢ়ଶͷ4PDLFUΦϒδΣΫτ
  10. αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial

    100 sock.write message ensure sock.close end αʔό ϦΫΤετΛड͚ͯϨεϙϯεΛฦ͢ɺͱ͍͏Ұ࿈ͷྲྀΕΛϧʔϓ
  11. αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial

    100 sock.write message ensure sock.close end αʔό ΫϥΠΞϯτ͔ΒϦΫΤετΛड৴͠ɺ ͦΕΛͦͷ··ΫϥΠΞϯτʹϨεϙϯεͱͯ͠ ૹ৴͢Δ؆୯ͳ5$1ΤίʔαʔόϓϩάϥϜ a׬੒
  12. ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message

    = sock.read puts message end ΫϥΠΞϯτ TPDLFUϥΠϒϥϦΛSFRVJSF 4PDLFUUDQϝιου
  13. ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message

    = sock.read puts message end ΫϥΠΞϯτ Ѽઌϗετ໊MPDBMIPTU Ѽઌϙʔτ൪߸
  14. ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message

    = sock.read puts message end ΫϥΠΞϯτ ΫϥΠΞϯτͱͯ͠ߦ͏ॲཧ
  15. ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message

    = sock.read puts message end ΫϥΠΞϯτ Ѽઌͷαʔόͱ઀ଓࡁΈͷঢ়ଶͷ 4PDLFUΦϒδΣΫτ
  16. ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message

    = sock.read puts message end ΫϥΠΞϯτ 4PDLFUΦϒδΣΫτʹॻ͖ࠐΈ αʔό΁ϦΫΤετϝοηʔδΛૹ৴ Ѽઌͷαʔόͱ઀ଓࡁΈͷঢ়ଶͷ 4PDLFUΦϒδΣΫτ
  17. ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message

    = sock.read puts message end ΫϥΠΞϯτ 4PDLFUΦϒδΣΫτΛಡΈࠐΈ αʔό͔ΒϨεϙϯεϝοηʔδΛऔಘ ϨεϙϯεϝοηʔδΛඪ४ग़ྗ Ѽઌͷαʔόͱ઀ଓࡁΈͷঢ়ଶͷ 4PDLFUΦϒδΣΫτ
  18. ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message

    = sock.read puts message end ΫϥΠΞϯτ ॲཧ͕ऴΘΔͱ4PDLFUΦϒδΣΫτ͸ࣗಈతʹΫϩʔζ Ѽઌͷαʔόͱ઀ଓࡁΈͷঢ়ଶͷ 4PDLFUΦϒδΣΫτ
  19. ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message

    = sock.read puts message end ΫϥΠΞϯτ αʔόʹϦΫΤετ )J Λૹ৴͠ɺ αʔό͔Βड৴ͨ͠ϨεϙϯεΛͦͷ··ग़ྗ͢Δ ؆୯ͳ5$1ΫϥΠΞϯτϓϩάϥϜ a׬੒
  20. 4PDLFUUDQ@TFSWFS@MPPQ4PDLFUUDQͷߏ଄ Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write

    message ensure sock.close end Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end αʔό ΫϥΠΞϯτ ΫϥΠΞϯτͱͷ઀ଓޙʹߦ͏࢓ࣄ αʔόͱͷ઀ଓޙʹߦ͏࢓ࣄ αʔόʵΫϥΠΞϯτؒͷ઀ଓཱ͕֬ͨ͠ޙʹߦ͏ॲཧΛ ֤ϝιουͷϒϩοΫ಺ʹهड़͍ͯ͠Δ
  21. Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message

    ensure sock.close end Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end αʔό ΫϥΠΞϯτ ωοτϫʔΫΛհ͓ͯ͠ޓ͍ʹ઀ଓཱ͕֬͢Δ·Ͱͷॲཧ͸ ͦΕͧΕͷϝιουࣗ਎͕ߦͳ͍ͬͯΔ 4PDLFUUDQ@TFSWFS@MPPQ4PDLFUUDQͷߏ଄ ΫϥΠΞϯτͱͷ઀ଓ αʔόͱͷ઀ଓ
  22. Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message

    ensure sock.close end Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end αʔό ΫϥΠΞϯτ ͦͷཪଆͰ3VCZ͸ͲͷΑ͏ʹιέοτΛѻ͍ɺ઀ଓ͍ͯ͠Δ 4PDLFUUDQ@TFSWFS@MPPQ4PDLFUUDQͷߏ଄ Ͳ͏΍ͬͯΫϥΠΞϯτͱ઀ଓ͍ͯ͠Δ  Ͳ͏΍ͬͯαʔόͱ઀ଓ͍ͯ͠Δ 
  23. 4PDLFUUDQ class Socket # ... def self.tcp(host, port, ... fast_fallback:

    tcp_fast_fallback, &) # ... end # ... end 4PDLFUUDQ͸4PDLFUΫϥεʹ Ϋϥεϝιουͱ࣮ͯ͠૷͞Ε͍ͯΔ FYUTPDLFUMJCTPDLFUSC
  24. 4PDLFUUDQ class Socket # ... def self.tcp(host, port, ... fast_fallback:

    tcp_fast_fallback, &) sock = if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end # ... end # ... end FYUTPDLFUMJCTPDLFUSC
  25. 4PDLFUUDQ class Socket # ... def self.tcp(host, port, ... fast_fallback:

    tcp_fast_fallback, &) sock = if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end # ... end # ... end FYUTPDLFUMJCTPDLFUSC ಛఆͷ৚݅Ͱ෼ذ ίʔυϦʔσΟϯάͷ༰қ͔͞Βɺ 
 ࠓճ͸ͪ͜ΒΛಡΈ·͢
  26. 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil,

    :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... end FYUTPDLFUMJCTPDLFUSC
  27. 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil,

    :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... end FYUTPDLFUMJCTPDLFUSC "EESJOGPGPSFBDI
  28. "EESJOGPGPSFBDI FYUTPDLFUMJCTPDLFUSC class Addrinfo # ... def self.foreach(nodename, service, ...,

    &block) Addrinfo.getaddrinfo(nodename, service, ...).each(&block) end # ... end
  29. class Addrinfo # ... def self.foreach(nodename, service, ..., &block) Addrinfo.getaddrinfo(nodename,

    service, ...).each(&block) end # ... end "EESJOGPGPSFBDI "EESJOGPHFUBEESJOGP FYUTPDLFUMJCTPDLFUSC
  30. "EESJOGPHFUBEESJOGP "EESJOGPHFUBEESJOGP͸ ౉͞Εͨϗετ໊ͱϙʔτ൪߸Λ*1ΞυϨεʹղܾ͠ɺ ͦͷ݁ՌҰཡΛ"EESJOGPΦϒδΣΫτͷ഑ྻͰฦ͢ϝιου (ྫ) Addrinfo.getaddrinfo("localhost", 4567, nil, :STREAM) =>

    [#<Addrinfo: 127.0.0.1 TCP (localhost)>, #<Addrinfo: ::1 TCP (localhost)>] ϗετ͕*1W*1W྆ํʹରԠ͍ͯ͠Δ৔߹ɺฦΓ஋ʹ͸ ͦͷ྆ํͷΞυϨεΛද͢"EESJOGPΦϒδΣΫτؚ͕·ΕΔ ϗετ໊ ϙʔτ൪߸ ໊લղܾͷώϯτ ղܾͰ͖ͨ*1ΞυϨεҰཡ
  31. "EESJOGPΦϒδΣΫτ "EESJOGPΦϒδΣΫτ*1ΞυϨε৘ใΛද͢ΦϒδΣΫτ (ྫ) addrinfo # => #<Addrinfo: 127.0.0.1 TCP (localhost)>

    addrinfo.ip_address # => "127.0.0.1" addrinfo.ipv4? # => true addrinfo.pfamily # => addrinfo.socktype # => "EESJOGPΦϒδΣΫτʹΞΫηε͢Δ͜ͱͰ ΞυϨεʹؔ͢Δ৘ใΛऔಘͨ͠Γૢ࡞͢Δ͜ͱ͕Ͱ͖Δ ΞυϨεϑΝϛϦ (IPv6 / IPv4) Λද͢਺஋ ௨৴ͷछྨ (ετϦʔϜ / σʔλάϥϜ) Λද͢਺஋
  32. class Addrinfo # ... def self.foreach(nodename, service, ..., &block) Addrinfo.getaddrinfo(nodename,

    service, ...).each(&block) end # ... end "EESJOGPGPSFBDI ྫɿ*1Wͱ*1W྆ํʹରԠ͍ͯ͠ΔϗετͰ ɹɹϗετ໊ͱͯ͠MPDBMIPTUΛ౉ͨ͠৔߹ "EESJOGPHFUBEESJOGP͸ϗετ໊Λ໊લղܾ͠ɺ *1WΞυϨεͱ*1WΞυϨεΛͦΕͧΕද͢ "EESJOGPΦϒδΣΫτΛཁૉʹ࣋ͭ഑ྻΛฦ͢ => [#<Addrinfo: 127.0.0.1 TCP (localhost)>, #<Addrinfo: ::1 TCP (localhost)>] "localhost" FYUTPDLFUMJCTPDLFUSC
  33. class Addrinfo # ... def self.foreach(nodename, service, ..., &block) Addrinfo.getaddrinfo(nodename,

    service, ...).each(&block) end # ... end "EESJOGPGPSFBDI "EESJOGPGPSFBDI͸͜ͷ഑ྻʹରͯ͠FBDIΛݺͼग़͠ɺ ֤"EESJOGPΦϒδΣΫτ͝ͱʹϒϩοΫΛ࣮ߦ͢Δ  "EESJOGPΦϒδΣΫτͷ഑ྻʹର͢Δ "SSBZFBDI FYUTPDLFUMJCTPDLFUSC
  34. 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil,

    :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... end ϒϩοΫม਺ʹ౉͞ΕΔ"EESJOGPΦϒδΣΫτΛ༻͍ͯ ϒϩοΫ಺ͷॲཧΛ࣮ߦ͢Δ "EESJOGPΦϒδΣΫτ FYUTPDLFUMJCTPDLFUSC ࠶ͼ "EESJOGPGPSFBDI͕࣮ߦ͢ΔϒϩοΫ
  35. 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil,

    :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... end FYUTPDLFUMJCTPDLFUSC "EESJOGPDPOOFDU
  36. "EESJOGPDPOOFDU class Addrinfo # ... def connect(...) connect_internal(nil, ...) end

    # ... end "EESJOGPDPOOFDU@JOUFUOBM FYUTPDLFUMJCTPDLFUSC
  37. "EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily,

    self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC
  38. "EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily,

    self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC 4PDLFUOFX
  39. "EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily,

    self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC 4PDLFUOFX ϗετ಺෦Ͱ৽͍͠ιέοτΛ࡞੒͠ɺ ɹͦΕΛ4PDLFUΦϒδΣΫτͱͯ͠ ɹѻ͑ΔΑ͏ʹͯ͠ฦ͢
  40. "EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily,

    self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC 4PDLFUOFX ➡︎ ͦͷ࣮ଶ͸$ݴޠͰ࣮૷ 3VCZͷ͞ΒͳΔ಺ଆΛ ͷ͍͍͖ͧͯ·͠ΐ͏ ϗετ಺෦Ͱ৽͍͠ιέοτΛ࡞੒͠ɺ ɹͦΕΛ4PDLFUΦϒδΣΫτͱͯ͠ ɹѻ͑ΔΑ͏ʹͯ͠ฦ͢
  41. 4PDLFUJOJUJBMJ[F void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket);

    // ... rb_define_method(rb_cSocket, "initialize", sock_initialize, -1); // ... } FYUTPDLFUTPDLFUD
  42. 4PDLFUJOJUJBMJ[F void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket);

    // ... rb_define_method(rb_cSocket, "initialize", sock_initialize, -1); // ... } 3VCZͷ$"1*Λ࢖ͬͯ 4PDLFUΫϥεͱ4PDLFUJOJUJBMJ[F͕ఆٛ͞Ε͍ͯΔ FYUTPDLFUTPDLFUD 4PDLFUΫϥεΛఆٛ 4PDLFUJOJUJBMJ[FΛఆٛ
  43. 4PDLFUJOJUJBMJ[F void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket);

    // ... rb_define_method(rb_cSocket, "initialize", sock_initialize, -1); // ... } FYUTPDLFUTPDLFUD 4PDLFUJOJUJBMJ[Fͷ಺෦࣮૷ 4PDLFUJOJUJBMJ[F͸ ࣮ମͱͯ͠͸TPDL@JOJUJBMJ[Fؔ਺ʹ࣮૷͞Ε͍ͯΔ
  44. TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock)

    { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } FYUTPDLFUTPDLFUD
  45. TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock)

    { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } ϝιουͷҾ਺ͷॲཧ FYUTPDLFUTPDLFUD
  46. TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock)

    { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } STPDL@TPDLFUؔ਺ FYUTPDLFUTPDLFUD
  47. TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock)

    { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } STPDL@TPDLFUؔ਺͸಺෦Ͱ STPDL@TPDLFUؔ਺ΛݺΜͰ͍Δ FYUTPDLFUTPDLFUD
  48. STPDL@TPDLFU static int rsock_socket0(int domain, int type, int proto) {

    // ... int result = socket(domain, type, proto); if (result == -1) return -1; rb_fd_fix_cloexec(result); #ifndef SOCK_NONBLOCK rsock_make_fd_nonblock(result); #endif return result; } FYUTPDLFUJOJUD
  49. STPDL@TPDLFU static int rsock_socket0(int domain, int type, int proto) {

    // ... int result = socket(domain, type, proto); if (result == -1) return -1; rb_fd_fix_cloexec(result); #ifndef SOCK_NONBLOCK rsock_make_fd_nonblock(result); #endif return result; } TPDLFU γεςϜίʔϧ  STPDL@TPDLFUؔ਺಺Ͱ TPDLFUͱ͍͏γεςϜίʔϧΛݺΜͰ͍Δ aॏཁ FYUTPDLFUJOJUD
  50. STPDL@TPDLFU static int rsock_socket0(int domain, int type, int proto) {

    // ... int result = socket(domain, type, proto); if (result == -1) return -1; rb_fd_fix_cloexec(result); #ifndef SOCK_NONBLOCK rsock_make_fd_nonblock(result); #endif return result; } ͜ͷϗετ಺ʹιέοτΛ࡞੒͢ΔΑ͏ Χʔωϧʹର໋ͯ͠ྩ͢Δ STPDL@TPDLFUؔ਺͸಺෦తʹTPDLFUΛݺͼग़͢͜ͱͰ ࣮ࡍʹϗετ಺ʹιέοτΛ࡞੒͍ͯ͠Δ FYUTPDLFUJOJUD TPDLFU γεςϜίʔϧ  ϗετ ιέοτ
  51. STPDL@TPDLFU static int rsock_socket0(int domain, int type, int proto) {

    // ... int result = socket(domain, type, proto); if (result == -1) return -1; rb_fd_fix_cloexec(result); #ifndef SOCK_NONBLOCK rsock_make_fd_nonblock(result); #endif return result; } TPDLFUγεςϜίʔϧ͸ɺ৽͘͠࡞੒ͨ͠ιέοτΛ ಛఆ͢ΔͨΊͷ൪߸ιέοτσΟεΫϦϓλΛฦ͢ ιέοτσΟεΫϦϓλΛऔಘ FYUTPDLFUJOJUD TPDLFU γεςϜίʔϧ 
  52. STPDL@TPDLFU static int rsock_socket0(int domain, int type, int proto) {

    // ... int result = socket(domain, type, proto); if (result == -1) return -1; rb_fd_fix_cloexec(result); #ifndef SOCK_NONBLOCK rsock_make_fd_nonblock(result); #endif return result; } औಘͨ͠ιέοτσΟεΫϦϓλΛฦͯ͠ऴྃ FYUTPDLFUJOJUD STPDL@TPDLFU͸৽͘͠࡞੒ͨ͠ιέοτͷ ιέοτσΟεΫϦϓλΛฦͯ͠ऴྃ͢Δ ιέοτσΟεΫϦϓλΛऔಘ TPDLFU γεςϜίʔϧ 
  53. TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock)

    { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } FYUTPDLFUTPDLFUD ࠶ͼ STPDL@TPDLFUؔ਺ ৽͍͠ιέοτΛ࡞੒ͯ͠ ιέοτσΟεΫϦϓλΛฦ͢  ಺෦ͰSTPDL@TPDLFUؔ਺ΛݺΜͰ͍Δ 
  54. TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock)

    { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } STPDL@TPDLFUؔ਺ FYUTPDLFUTPDLFUD STPDL@TPDLFUؔ਺ͷฦΓ஋ ৽͘͠࡞੒ͨ͠ιέοτͷ ιέοτσΟεΫϦϓλ Λม਺GEʹ֨ೲ ࠶ͼ ৽͍͠ιέοτΛ࡞੒ͯ͠ ιέοτσΟεΫϦϓλΛฦ͢  ಺෦ͰSTPDL@TPDLFUؔ਺ΛݺͿ 
  55. TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock)

    { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } STPDL@JOJU@TPDLؔ਺ FYUTPDLFUTPDLFUD STPDL@JOJU@TPDLؔ਺͸ม਺GEͷιέοτσΟεΫϦϓλΛ σʔλͱͯ͠อ࣋͢Δ4PDLFUΦϒδΣΫτΛ৽ͨʹ࡞੒͢Δ
  56. TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock)

    { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } ฦΓ஋ΛSFUVSO ࠷ޙʹɺTPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[F ͸ ࡞੒ͨ͠4PDLFUΦϒδΣΫτΛฦͯ͠ऴྃ FYUTPDLFUTPDLFUD
  57. TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock)

    { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } 4PDLFUOFXͷ಺෦࣮૷͸͜͜·Ͱ FYUTPDLFUTPDLFUD
  58. "EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily,

    self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC 4PDLFUOFX ࠶ͼ ϗετ಺෦Ͱ৽͍͠ιέοτΛ࡞੒͠ɺ ɹ͜ΕΛϥοϓ͢Δ4PDLFUΦϒδΣΫτΛฦ͢
  59. "EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily,

    self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC ࡞੒ͨ͠4PDLFUΦϒδΣΫτΛม਺TPDLʹ֨ೲ ม਺TPDLʹରͯ͠4PDLFUDPOOFDU TFMGѼઌͷΞυϨε৘ใ "EESJOGPΦϒδΣΫτ 
  60. "EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily,

    self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC 4PDLFUDPOOFDU΋$Ͱ࣮૷͞Ε͍ͯΔ ࡞੒ͨ͠4PDLFUΦϒδΣΫτΛม਺TPDLʹอଘ TFMGѼઌͷΞυϨε৘ใ "EESJOGPΦϒδΣΫτ  ม਺TPDLʹରͯ͠4PDLFUDPOOFDU
  61. 4PDLFUDPOOFDU void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket);

    // ... rb_define_method(rb_cSocket, "initialize", sock_initialize, -1); rb_define_method(rb_cSocket, "connect", sock_connect, 1); // ... } FYUTPDLFUTPDLFUD 4PDLFUDPOOFDUΛఆٛ 4PDLFUΫϥεΛఆٛ 4PDLFUDPOOFDUͷ಺෦࣮૷ 4PDLFUDPOOFDU͸ ࣮ମͱͯ͠͸TPDL@DPOOFDUؔ਺ʹ࣮૷͞Ε͍ͯΔ
  62. static VALUE sock_connect(VALUE self, VALUE addr) { // ... int

    result = rsock_connect( self, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, RUBY_IO_TIMEOUT_DEFAULT ); // ... return INT2FIX(result); } TPDL@DPOOFDU 4PDLFUDPOOFDUͷ࣮ମ FYUTPDLFUTPDLFUD
  63. static VALUE sock_connect(VALUE self, VALUE addr) { // ... int

    result = rsock_connect( self, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, RUBY_IO_TIMEOUT_DEFAULT ); // ... return INT2FIX(result); } TPDL@DPOOFDU 4PDLFUDPOOFDUͷ࣮ମ sock.connect(self) 4PDLFUDPOOFDUͷϨγʔό 4PDLFUΦϒδΣΫτ  FYUTPDLFUTPDLFUD
  64. static VALUE sock_connect(VALUE self, VALUE addr) { // ... int

    result = rsock_connect( self, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, RUBY_IO_TIMEOUT_DEFAULT ); // ... return INT2FIX(result); } TPDL@DPOOFDU 4PDLFUDPOOFDUͷ࣮ମ sock.connect(self) ѼઌͷΞυϨε৘ใΛอ࣋͢Δ 4PDLFUDPOOFDUͷҾ਺ "EESJOGPΦϒδΣΫτ  FYUTPDLFUTPDLFUD
  65. static VALUE sock_connect(VALUE self, VALUE addr) { // ... int

    result = rsock_connect( self, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, RUBY_IO_TIMEOUT_DEFAULT ); // ... return INT2FIX(result); } TPDL@DPOOFDU 4PDLFUDPOOFDUͷ࣮ମ STPDL@DPOOFDUؔ਺ FYUTPDLFUTPDLFUD Ϩγʔόͷ4PDLFUΦϒδΣΫτ Ҿ਺Ͱड͚औͬͨѼઌͷΞυϨε৘ใ sock.connect(self)
  66. TPDL@DPOOFDU 4PDLFUDPOOFDUͷ࣮ମ static VALUE sock_connect(VALUE self, VALUE addr) { //

    ... int result = rsock_connect( self, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, RUBY_IO_TIMEOUT_DEFAULT ); // ... return INT2FIX(result); } STPDL@DPOOFDUؔ਺͸಺෦Ͱ DPOOFDU@CMPDLJOHؔ਺ΛݺΜͰ͍Δ FYUTPDLFUTPDLFUD
  67. DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg =

    data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } FYUTPDLFUJOJUD
  68. DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg =

    data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } FYUTPDLFUJOJUD Ҿ਺EBUB DPOOFDU@CMPDLJOHؔ਺͸Ҿ਺EBUBΛհͯ͠ STPDL@DPOOFDUؔ਺ʹ౉ͨ͠Ҿ਺ͷத਎Λड͚औΔ ɾϨγʔόͷ4PDLFUΦϒδΣΫτ͔Β औΓग़ͨ͠಺෦৘ใ ɾѼઌͷΞυϨε৘ใ ʜΛؚΉ
  69. DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg =

    data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } FYUTPDLFUJOJUD Ҿ਺EBUBͷத਎Λม਺BSHʹ֨ೲ
  70. DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg =

    data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } DPOOFDU@CMPDLJOHؔ਺಺Ͱ γεςϜίʔϧDPOOFDUΛݺͿ aॏཁ DPOOFDU γεςϜίʔϧ  ࢦఆͷιέοτΛ࢖ͬͯѼઌͱͷ઀ଓΛ։࢝͢Δ FYUTPDLFUJOJUD ΫϥΠΞϯτ ઀ଓΛ։࢝ Ѽઌ  ྫ
  71. DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg =

    data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } ม਺BSH͔ΒιέοτσΟεΫϦϓλΛऔΓग़͠ɺ DPOOFDUͷୈҰҾ਺ʹ౉͢ɻ ͜ΕʹΑΓʮͲͷιέοτΛ࢖͏͔ʯΛࢦఆ͍ͯ͠Δ FYUTPDLFUJOJUD ม਺BSH͔ΒऔΓग़ͨ͠ιέοτσΟεΫϦϓλ
  72. DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg =

    data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } ม਺BSH͔ΒऔΓग़ͨ͠઀ଓઌͷΞυϨε৘ใ ม਺BSH͔ΒѼઌͷΞυϨε৘ใΛऔΓग़͠ɺ DPOOFDUͷୈೋҾ਺ʹ౉͢ɻ ͜ΕʹΑΓʮͲ͜Ѽʹ઀ଓ͢Δ͔ʯΛࢦఆ͍ͯ͠Δ FYUTPDLFUJOJUD
  73. DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg =

    data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } ઀ଓʹ੒ޭ͢ΔͱDPOOFDU͸଴ػΛղআ͠ ౰֘ιέοτ͸Ѽઌϗετͱ઀ଓࡁΈͷঢ়ଶʹͳΔ FYUTPDLFUJOJUD ઀ଓࢼߦ։࢝ޙɺ઀ଓঢ়ଶ͕֬ఆ͢Δ·Ͱ଴ػ͢Δ ˞౰֘ιέοτ͕ϊϯϒϩοΩϯάϞʔυʹઃఆ͞Ε͍ͯͳ͍৔߹ ˞ ΫϥΠΞϯτ αʔό aa઀ଓཱ֬
  74. DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg =

    data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } 4PDLFUDPOOFDUͷ಺෦࣮૷͸͜͜·Ͱ FYUTPDLFUJOJUD
  75. "EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily,

    self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC ࠶ͼ 4PDLFUDPOOFDU ࢦఆͷιέοτΛ࢖ͬͯѼઌʹ઀ଓΛ։࢝͢Δ
  76. "EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily,

    self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end "EESJOGPDPOOFDU@JOUFSOBM͸ɺѼઌϗετͱ ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛฦͯ͠ऴྃ αʔόͱ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛฦ͢ FYUTPDLFUMJCTPDLFUSC 4PDLFUDPOOFDU
  77. 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil,

    :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... ret end FYUTPDLFUMJCTPDLFUSC ࠶ͼ "EESJOGPDPOOFDU 4PDLFUΦϒδΣΫτΛ࡞੒ˠ઀ଓ  ಺෦Ͱ"EESJOGPDPOOFDU@JOUFSOBMΛݺͿ 
  78. 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil,

    :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... ret end "EESJOGPDPOOFDUͷฦΓ஋ͱͯ͠ ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛม਺SFUʹอଘ্ͨ͠ "EESJOGPGPSFBDIͷϧʔϓΛCSFBL ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛ ม਺TPDLʹอଘ ม਺TPDLΛม਺SFUʹอଘͯ͠CSFBL FYUTPDLFUMJCTPDLFUSC
  79. 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil,

    :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... ret end ࠷ޙʹม਺SFU ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτ Λ ฦͯ͠4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL͸ऴྃ ฦΓ஋ FYUTPDLFUMJCTPDLFUSC
  80. 4PDLFUUDQ def self.tcp(host, port, ... fast_fallback: tcp_fast_fallback, &) sock =

    if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end if block_given? begin yield sock ensure sock.close end else sock end end FYUTPDLFUMJCTPDLFUSC ࠶ͼ 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛऔಘ
  81. 4PDLFUUDQ def self.tcp(host, port, ... fast_fallback: tcp_fast_fallback, &) sock =

    if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end if block_given? begin yield sock ensure sock.close end else sock end end FYUTPDLFUMJCTPDLFUSC ฦΓ஋ͷ4PDLFUΦϒδΣΫτΛม਺TPDLʹ֨ೲ 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDLͷฦΓ஋Ͱ͋Δ ઀ଓࡁΈ4PDLFUΦϒδΣΫτΛม਺TPDLʹอଘ 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛऔಘ
  82. 4PDLFUUDQ def self.tcp(host, port, ... fast_fallback: tcp_fast_fallback, &) sock =

    if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end if block_given? begin yield sock ensure sock.close end else sock end end ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛ࢖ͬͯ 4PDLFUUDQͷϒϩοΫΛ࣮ߦ͢Δ FYUTPDLFUMJCTPDLFUSC Socket.tcp(...) do |sock| sock.write "Hi" message = sock.read puts message end
  83. 4PDLFUUDQ def self.tcp(host, port, ... fast_fallback: tcp_fast_fallback, &) sock =

    if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end if block_given? begin yield sock ensure sock.close end else sock end end ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛ࢖ͬͯ 4PDLFUUDQͷϒϩοΫΛ࣮ߦ͢Δ Socket.tcp(...) do |sock| sock.write "Hi" message = sock.read puts message end aΰʔϧ FYUTPDLFUMJCTPDLFUSC
  84. 4PDLFUUDQ@TFSWFS@MPPQ class Socket # ... def self.tcp_server_loop(host=nil, port, &b) tcp_server_sockets(host,

    port) {|sockets| accept_loop(sockets, &b) } end # ... end FYUTPDLFUMJCTPDLFUSC
  85. class Socket # ... def self.tcp_server_loop(host=nil, port, &b) tcp_server_sockets(host, port)

    {|sockets| accept_loop(sockets, &b) } end # ... end 4PDLFUUDQ@TFSWFS@MPPQ 4PDLFUUDQ@TFSWFS@TPDLFUT ϗετ໊ ϙʔτ൪߸ FYUTPDLFUMJCTPDLFUSC 4PDLFUUDQ@TFSWFS@TPDLFUTΛݺͼग़͢ αʔόࣗ਎ͷ
  86. 4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets

    = tcp_server_sockets_port0(host) else last_error = nil sockets = [] begin # ... rescue Exception sockets.each(&:close) raise end # ... end end ϗετ໊ɾϙʔτ൪߸ FYUTPDLFUMJCTPDLFUSC
  87. 4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets

    = tcp_server_sockets_port0(host) else last_error = nil sockets = [] begin # ... rescue Exception sockets.each(&:close) raise end # ... end end ϙʔτ൪߸ʹΛ౉͍ͯ͠Δ৔߹ ϙʔτ൪߸ʹҎ֎Λ౉͍ͯ͠Δ৔߹ ίʔυϦʔσΟϯάͷ༰қ͔͞Βɺ ࠓճ͸ͪ͜ΒΛಡΈ·͢ ϗετ໊ɾϙʔτ൪߸ FYUTPDLFUMJCTPDLFUSC
  88. 4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ...

    Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end FYUTPDLFUMJCTPDLFUSC ˞if port == 0ͷelseઅͷத
  89. 4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ...

    Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end "EESJOGPGPSFBDI FYUTPDLFUMJCTPDLFUSC ˞if port == 0ͷelseઅͷத αʔόࣗ਎ͷϗετ໊ͷ໊લղܾΛߦ͏
  90. 4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ...

    Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end [#<Addrinfo: 127.0.0.1 TCP (localhost)>, #<Addrinfo: ::1 TCP (localhost)>] FYUTPDLFUMJCTPDLFUSC "localhost" "EESJOGPΦϒδΣΫτ ˞if port == 0ͷelseઅͷத ˞ྫ ˞ྫ ղܾͨ͠*1ΞυϨεΛද͢"EESJOGPΦϒδΣΫτ͕ ϒϩοΫม਺BJʹ౉ͬͯ͘Δ
  91. 4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ...

    Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end "EESJOGPMJTUFO FYUTPDLFUMJCTPDLFUSC ˞if port == 0ͷelseઅͷத "EESJOGPΦϒδΣΫτ
  92. "EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol)

    begin # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC
  93. "EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol)

    begin # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC 4PDLFUOFX ৽͍͠4PDLFUΦϒδΣΫτΛ࡞੒͢Δ
  94. "EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol)

    begin # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC ม਺TPDLʹରͯ͠4PDLFUCJOE TFMGαʔόࣗ਎ͷΞυϨε৘ใ "EESJOGPΦϒδΣΫτ  ࡞੒ͨ͠4PDLFUΦϒδΣΫτʹରͯ͠ 4PDLFUCJOEϝιουΛݺͿ ࡞੒ͨ͠4PDLFUΦϒδΣΫτΛม਺TPDLʹ֨ೲ
  95. 4PDLFUCJOE void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket);

    // ... rb_define_method(rb_cSocket, "bind", sock_bind, 1); // ... } 4PDLFUCJOE͸ ࣮ମͱͯ͠͸TPDL@CJOEؔ਺ʹ࣮૷͞Ε͍ͯΔ FYUTPDLFUTPDLFUD 4PDLFUCJOEΛఆٛ 4PDLFUΫϥεΛఆٛ 4PDLFUCJOEͷ಺෦࣮૷
  96. TPDL@CJOE 4PDLFUCJOEͷ࣮ମ static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE

    rai; rb_io_t *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } FYUTPDLFUTPDLFUD
  97. TPDL@CJOE 4PDLFUCJOEͷ࣮ମ static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE

    rai; rb_io_t *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } sock.bind(self) ୈҰҾ਺ʜ4PDLFUCJOEͷϨγʔό 4PDLFUΦϒδΣΫτ  ୈೋҾ਺ʜ4PDLFUCJOEͷҾ਺ "EESJOGPΦϒδΣΫτ  ࣗ਎ͷΞυϨε৘ใΛอ࣋͢Δ FYUTPDLFUTPDLFUD
  98. static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t

    *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ Ϩγʔόͷ4PDLFUΦϒδΣΫτ͔Β ಺෦৘ใΛऔಘͯ͠ม਺GQUSʹอଘ FYUTPDLFUTPDLFUD (FU0QFO'JMFϚΫϩ
  99. static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t

    *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ TPDL@CJOEؔ਺಺ͰγεςϜίʔϧCJOEΛݺΜͰ͍Δ aॏཁ FYUTPDLFUTPDLFUD ࢦఆͷιέοτʹಛఆͷΞυϨεΛඥ͚ͮΔ CJOE γεςϜίʔϧ 
  100. static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t

    *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ ม਺GQUS͔ΒऔΓग़ͨ͠ιέοτσΟεΫϦϓλΛ CJOEͷୈҰҾ਺ʹ౉͢ɻ ͜ΕʹΑΓʮͲͷιέοτΛ࢖͏͔ʯΛࢦఆ͍ͯ͠Δ ม਺GQUS͔ΒऔΓग़ͨ͠ιέοτσΟεΫϦϓλ FYUTPDLFUTPDLFUD
  101. static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t

    *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ CJOEͷୈೋҾ਺ʹαʔόࣗ਎ͷΞυϨε৘ใΛ౉͢ɻ ͜ΕʹΑΓʮͲͷΞυϨεΛιέοτʹඥ͚ͮΔ͔ʯΛ ࢦఆ͍ͯ͠Δ ࣗ਎ͷΞυϨε৘ใ FYUTPDLFUTPDLFUD
  102. static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t

    *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ CJOEΛݺͼग़͢͜ͱʹΑΓɺ ʮͲͷιέοτ͕Ͳͷ*1ΞυϨεͰ ɹϦΫΤετΛ଴ػ͢Δ͔ʯΛࢦఆ͍ͯ͠Δ FYUTPDLFUTPDLFUD ϦΫΤετΛ଴ػ͢ΔΞυϨε *1ΞυϨεΛඥ෇͚  ྫ
  103. static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t

    *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ 4PDLFUCJOEͷ಺෦࣮૷͸͜͜·Ͱ FYUTPDLFUTPDLFUD *1ΞυϨεΛඥ෇͚
  104. "EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol)

    begin sock.ipv6only! if self.ipv6? # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC 4PDLFUCJOE ࢦఆͷιέοτͱࣗ਎ͷΞυϨεΛඥ͚ͮΔ ࠶ͼ
  105. "EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol)

    begin sock.ipv6only! if self.ipv6? # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC 4PDLFUMJTUFO
  106. 4PDLFUMJTUFO void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket);

    // ... rb_define_method(rb_cSocket, "bind", sock_bind, 1); rb_define_method(rb_cSocket, "listen", rsock_sock_listen, 1); // ... } FYUTPDLFUTPDLFUD 4PDLFUΫϥεΛఆٛ 4PDLFUMJTUFO͸ ࣮ମͱͯ͠͸STPDL@TPDL@MJTUFOؔ਺ʹ࣮૷͞Ε͍ͯΔ 4PDLFUMJTUFOΛఆٛ 4PDLFUMJTUFOͷ಺෦࣮૷
  107. STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr;

    int backlog; backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); }
  108. STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr;

    int backlog; backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); } 4PDLFUMJTUFOͷϨγʔό 4PDLFUΦϒδΣΫτ  Ϩγʔόͷ4PDLFUΦϒδΣΫτ͔Β ಺෦৘ใΛऔಘͯ͠ม਺GQUSʹอଘ (FU0QFO'JMFϚΫϩ
  109. VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog;

    backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); } STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ STPDL@TPDL@MJTUFOؔ਺಺Ͱ γεςϜίʔϧMJOTUFOΛݺΜͰ͍Δ aॏཁ MJTUFO γεςϜίʔϧ  ࢦఆͷιέοτͰ઀ଓΛ଴ͪड͚Δ
  110. VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog;

    backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); } STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ ม਺GQUS͔ΒऔΓग़ͨ͠ιέοτσΟεΫϦϓλ ม਺GQUS͔ΒऔΓग़ͨ͠ιέοτσΟεΫϦϓλΛ MJTUFOͷୈҰҾ਺ʹ౉͢ɻ ͜ΕʹΑΓʮͲͷιέοτΛ࢖͏͔ʯΛࢦఆ͍ͯ͠Δ
  111. VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog;

    backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); } STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ MJTUFOΛݺͼग़͢͜ͱʹΑΓɺ ࣮ࡍʹ͜ͷιέοτͰͷ઀ଓ଴ػ͕։࢝͢Δ  ྫ ઀ଓ଴ͪ
  112. VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog;

    backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); } STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ 4PDLFUMJTUFOͷ಺෦࣮૷͸͜͜·Ͱ ઀ଓ଴ͪ
  113. "EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol)

    begin sock.ipv6only! if self.ipv6? # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC ࠶ͼ 4PDLFUMJTUFO ࢦఆͷιέοτͰ઀ଓΛ଴ػ͢Δ
  114. "EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol)

    begin sock.ipv6only! if self.ipv6? # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτ 4PDLFUΦϒδΣΫτΛฦͯ͠"EESJOGPMJTUFOΛऴྃ
  115. 4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ...

    Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end ࠶ͼ ˞if port == 0ͷelseઅͷத "EESJOGPMJTUFO ৽͘͠ιέοτΛ࡞੒ ɹˠࣗ෼ࣗ਎ͷΞυϨεΛඥ෇͚ ɹˠ઀ଓ଴ػΛ։࢝
  116. 4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ...

    Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end "EESJOGPMJTUFOͷฦΓ஋ͱͯ͠ ઀ଓ଴ػΛ։࢝ͨ͠4PDLFUΦϒδΣΫτΛ ഑ྻTPDLFUTʹ֨ೲ ม਺Tʹ֨ೲͨ͠4PDLFUΦϒδΣΫτΛ഑ྻTPDLFUTʹ֨ೲ ˞if port == 0ͷelseઅͷத "EESJOGPMJTUFO ฦΓ஋ͷ4PDLFUΦϒδΣΫτΛม਺Tʹ֨ೲ
  117. last_error = nil sockets = [] begin # ... Addrinfo.foreach(host,

    port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end [#<Addrinfo: 127.0.0.1 TCP (localhost)>, #<Addrinfo: ::1 TCP (localhost)>] FYUTPDLFUMJCTPDLFUSC "localhost" ͜͜·Ͱͷॲཧ ιέοτͷ࡞੒ɺΞυϨεͷඥ෇͚ɺ ઀ଓ଴ػ։࢝ɺ഑ྻ΁ͷอଘ Λɺ໊લղܾͰऔಘͨ͠ ͢΂ͯͷ"EESJOGPΦϒδΣΫτʹରͯ͠܁Γฦ͢ ˞ྫ ˞ྫ "EESJOGPMJTUFO 4PDLFUUDQ@TFSWFS@TPDLFUT
  118. 4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets

    = tcp_server_sockets_port0(host) else end if block_given? begin yield sockets ensure sockets.each(&:close) end else sockets end end ઌ΄Ͳ·Ͱͷॲཧ 4PDLFUUDQ@TFSWFS@TPDLFUTϝιουͷଓ͖  "EESJOGPGPSFBDI͕ऴྃͯ͠ɺ if port == 0ͷelseઅΛൈ͚ͨޙ Ҿ͖ଓ͖ ഑ྻTPDLFUTʹ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτ͕อଘ͞Ε͍ͯΔ  FYUTPDLFUMJCTPDLFUSC
  119. 4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets

    = tcp_server_sockets_port0(host) else end if block_given? begin yield sockets ensure sockets.each(&:close) end else sockets end end ͜ͷϝιουͷݺͼग़࣌͠ʹ౉͞Ε͍ͯͨ ϒϩοΫΛ࣮ߦ͢Δ def self.tcp_server_loop(host=nil, port, &b) tcp_server_sockets(host, port) {|sockets| accept_loop(sockets, &b) } end ઌ΄Ͳ·Ͱͷॲཧ FYUTPDLFUMJCTPDLFUSC ϒϩοΫ
  120. 4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets

    = tcp_server_sockets_port0(host) else end if block_given? begin yield sockets ensure sockets.each(&:close) end else sockets end end def self.tcp_server_loop(host=nil, port, &b) tcp_server_sockets(host, port) {|sockets| accept_loop(sockets, &b) } end 4PDLFUBDDFQU@MPPQ ઌ΄Ͳ·Ͱͷॲཧ FYUTPDLFUMJCTPDLFUSC
  121. 4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets

    = tcp_server_sockets_port0(host) else end if block_given? begin yield sockets ensure sockets.each(&:close) end else sockets end end def self.tcp_server_loop(host=nil, port, &b) tcp_server_sockets(host, port) {|sockets| accept_loop(sockets, &b) } end ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻ ઌ΄Ͳ·Ͱͷॲཧ FYUTPDLFUMJCTPDLFUSC
  122. 4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets"

    end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end FYUTPDLFUMJCTPDLFUSC
  123. 4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets"

    end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻ 4PDLFUBDDFQU@MPPQ͸Ҿ਺ͱͯ͠ ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻΛड͚औΔ FYUTPDLFUMJCTPDLFUSC
  124. 4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets"

    end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end ϧʔϓॲཧ FYUTPDLFUMJCTPDLFUSC
  125. 4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets"

    end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end ϧʔϓॲཧ αʔό͸ΫϥΠΞϯτ͔ΒԿ౓΋ ϦΫΤετΛड͚ΔͨΊɺ Ұ࿈ͷॲཧΛϧʔϓͯ͠ߦ͍ͬͯΔ FYUTPDLFUMJCTPDLFUSC
  126. 4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets"

    end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end *0TFMFDU TPDLFUT઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻ *0TFMFDUʹ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻΛ ౉ͯ͠ݺͼग़͢ FYUTPDLFUMJCTPDLFUSC
  127. 4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets"

    end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end *0TFMFDU TPDLFUT઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻ *0TFMFDU͸ Ҿ਺ʹ౉͍ͯ͠Δ4PDLFUΦϒδΣΫτͷ͍ͣΕ͔ʹ ϦΫΤετ͕ಧ͘·Ͱɺ͜͜ͰॲཧΛϒϩοΫ͢Δ FYUTPDLFUMJCTPDLFUSC
  128. 4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets"

    end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end *0TFMFDU TPDLFUT઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻ ͍ͣΕ͔ͷ4PDLFUΦϒδΣΫτʹϦΫΤετ͕ಧ͘ͱɺ FYUTPDLFUMJCTPDLFUSC
  129. 4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets"

    end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end *0TFMFDUͷฦΓ஋ SFBEBCMFϦΫΤετ͕ಧ͍ͨ4PDLFUΦϒδΣΫτͷ഑ྻ *0TFMFDU͸଴ػΛղআ͠ɺ ର৅ͷ4PDLFUΦϒδΣΫτΛཁૉʹ࣋ͭ ഑ྻSFBEBCMFΛฦ͢ FYUTPDLFUMJCTPDLFUSC
  130. 4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets"

    end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end 4PDLFUBDDFQU@OPOCMPDL ϦΫΤετ͕ಧ͍ͨ4PDLFUΦϒδΣΫτʹରͯ͠ ॱʹ4PDLFUBDDFQU@OPOCMPDLϝιουΛݺͼग़͢ ϦΫΤετ͕ಧ͍ͨ4PDLFUΦϒδΣΫτ FYUTPDLFUMJCTPDLFUSC
  131. 4PDLFU@@BDDFQU@OPOCMPDL void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket);

    // ... /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cSocket, "__accept_nonblock", sock_accept_nonblock, 1); // ... } FYUTPDLFUTPDLFUD 4PDLFU@@BDDFQU@OPOCMPDL͸$Ͱ࣮૷͞Ε͍ͯΔ  TPDLFUSCϑΝΠϧ͔Βݺͼग़ͨ͢Ί͚ͩʹ࣮૷͞Ε͍ͯΔ 4PDLFUΫϥεΛఆٛ 4PDLFU@@BDDFQU@OPOCMPDLΛఆٛ 4PDLFU@@BDDFQU@OPOCMPDLͷ಺෦࣮૷
  132. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ FYUTPDLFUTPDLFUD
  133. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ FYUTPDLFUTPDLFUD 4PDLFUBDDFQU@OPOCMPDLͷϨγʔό 4PDLFUΦϒδΣΫτ 
  134. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ FYUTPDLFUTPDLFUD Ϩγʔόͷ4PDLFUΦϒδΣΫτͱ͸ผʹɺ ৽͍͠4PDLFUΦϒδΣΫτΛ֨ೲ͢ΔͨΊͷ ม਺TPDLΛએݴ ͋ͱͰ࢖͏
  135. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ FYUTPDLFUTPDLFUD 4PDLFUBDDFQU@OPOCMPDLͷϨγʔό 4PDLFUΦϒδΣΫτ  Ϩγʔόͷ4PDLFUΦϒδΣΫτ͔Β ಺෦৘ใΛऔಘͯ͠ม਺GQUSʹอଘ (FU0QFO'JMFϚΫϩ
  136. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ STPDL@T@BDDFQU@OPOCMPDLؔ਺ FYUTPDLFUTPDLFUD
  137. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ Ϩγʔόͷ4PDLFUΦϒδΣΫτͷ಺෦৘ใ FYUTPDLFUTPDLFUD
  138. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ STPDL@T@BDDFQU@OPOCMPDLؔ਺͸ ಺෦ͰDMPFYFD@BDDFQUؔ਺ΛݺΜͰ͍Δ FYUTPDLFUTPDLFUD
  139. DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len)

    { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } FYUTPDLFUJOJUD
  140. DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len)

    { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } FYUTPDLFUJOJUD Ϩγʔόͷ4PDLFUΦϒδΣΫτͷιέοτσΟεΫϦϓλ
  141. DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len)

    { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } DMPFYFD@BDDFQUؔ਺಺ͰγεςϜίʔϧ BDDFQUΛݺͿ BDDFQU γεςϜίʔϧ  aॏཁ FYUTPDLFUJOJUD ΫϥΠΞϯτ͔ΒͷϦΫΤετΛ ࢦఆͷιέοτͰड͚ೖΕΔ ˞JGEFG)"7&@"$$&15͕GBMTFͷ৔߹
  142. DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len)

    { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } FYUTPDLFUJOJUD Ҿ਺ʹιέοτσΟεΫϦϓλΛ౉͠ɺ ʮͲͷιέοτͷϦΫΤετΛड͚෇͚Δͷ͔ʯΛࢦఆ Ϩγʔόͷ4PDLFUΦϒδΣΫτͷιέοτσΟεΫϦϓλ
  143. DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len)

    { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } BDDFQU͕ϦΫΤετΛड͚෇͚Δͱ FYUTPDLFUJOJUD ΫϥΠΞϯτ αʔό BDDFQU
  144. DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len)

    { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } ϦΫΤετΛ଴ͪड͚͍ͯΔιέοτ B ͱ͸ผʹ ΫϥΠΞϯτͱ઀ଓ͞Εͨ৽͍͠ιέοτ C ͕࡞੒͞ΕΔ FYUTPDLFUJOJUD ΫϥΠΞϯτ aa઀ଓཱ֬ αʔό C B
  145. DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len)

    { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } ΫϥΠΞϯτͱ઀ଓࡁΈͷιέοτͷ ιέοτσΟεΫϦϓλ BDDFQU͸৽͘͠࡞੒͞Εͨιέοτ C ͷ ιέοτσΟεΫϦϓλΛฦ͢ FYUTPDLFUJOJUD ΫϥΠΞϯτ αʔό C B aa઀ଓཱ֬
  146. DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len)

    { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } DMPFYFD@BDDFQUؔ਺͸৽͘͠࡞੒͞Εͨιέοτ C ͷ ιέοτσΟεΫϦϓλΛฦͯ͠ऴྃ FYUTPDLFUJOJUD ΫϥΠΞϯτ αʔό C B aa઀ଓཱ֬
  147. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ FYUTPDLFUTPDLFUD ࠶ͼ STPDL@T@BDDFQU@OPOCMPDLؔ਺  ಺෦ͰDMPFYFD@BDDFQUؔ਺ΛݺͿ 
  148. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } FYUTPDLFUTPDLFUD STPDL@T@BDDFQU@OPOCMPDLؔ਺͸ ৽͘͠࡞੒ͨ͠ૉͷιέοτΛ 4PDLFUΦϒδΣΫτʹม׵ͯ͠ฦ͢ TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ
  149. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } FYUTPDLFUTPDLFUD ৽͍͠4PDLFUΦϒδΣΫτΛ֨ೲ ৽͍͠4PDLFUΦϒδΣΫτΛ֨ೲ͢ΔͨΊͷม਺TPDLΛએݴ TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ STPDL@T@BDDFQU@OPOCMPDLؔ਺͸ ৽͘͠࡞੒ͨ͠ૉͷιέοτΛ 4PDLFUΦϒδΣΫτʹม׵ͯ͠ฦ͢
  150. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } FYUTPDLFUTPDLFUD TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ 4PDLFUΦϒδΣΫτͱ઀ଓઌΞυϨεΛද͢"EESJOGPΦϒδΣΫτΛ഑ྻʹͯ͠ฦ͢
  151. static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE

    sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } FYUTPDLFUTPDLFUD TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ 4PDLFU@@BDDFQU@OPOCMPDLͷ಺෦࣮૷͸͜͜·Ͱ
  152. 4PDLFUBDDFQU@MPPQ ࠶ͼ def self.accept_loop(*sockets) # ... loop { readable, _,

    _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end 4PDLFUBDDFQU@OPOCMPDL ઀ଓΛड͚෇͚Δ
  153. def self.accept_loop(*sockets) # ... loop { readable, _, _ =

    IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end 4PDLFUBDDFQU@MPPQ 4PDLFUBDDFQU@OPOCMPDLͷฦΓ஋͔Β ม਺TPDLʹΫϥΠΞϯτͱ઀ଓࡁΈͷ ৽͍͠4PDLFUΦϒδΣΫτΛ֨ೲ 4PDLFUBDDFQU@OPOCMPDL ઀ଓΛड͚෇͚Δ
  154. def self.accept_loop(*sockets) # ... loop { readable, _, _ =

    IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end Socket.tcp_server_loop(...) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end 4PDLFUBDDFQU@MPPQ ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛ࢖ͬͯϒϩοΫΛ࣮ߦ
  155. 4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) # ... loop { readable, _, _

    = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛ࢖ͬͯϒϩοΫΛ࣮ߦ aΰʔϧ Socket.tcp_server_loop(...) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end
  156. ιέοτ͓ͬͯ΋͠Ζ͍ ΫϥΠΞϯτͱαʔόɺͦΕͧΕ͕Ұ࿈ͷखଓ͖ʹԊͬͯ ιέοτ"1*Λૢ࡞͢Δ͜ͱʹΑͬͯɺ ΫϥΠΞϯτ αʔό ιέοτ ɾ ɾ ɾ ɾ

    γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ ɾ ɾ γεςϜίʔϧ γεςϜίʔϧ socket connect socket bind listen accept ˞5$1ͷ৔߹
  157. ιέοτ͓ͬͯ΋͠Ζ͍ ιέοτΛ௨ͯ͡ɺωοτϫʔΫͷ྆୺ʹ͍Δϗετಉ࢜Ͱ ίϛϡχέʔγϣϯΛऔΔ͜ͱ͕Ͱ͖Δ ΫϥΠΞϯτ αʔό Ϩεϙϯε ϦΫΤετ ɾ ɾ ɾ

    ɾ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ ɾ ɾ γεςϜίʔϧ γεςϜίʔϧ socket connect socket bind listen accept ˞5$1ͷ৔߹
  158. 4PDLFUUDQ4PDLFUUDQ@TFSWFS@MPPQͷେ෦෼͸3VCZ࣮૷ 3VCZ͓ͬͯ΋͠Ζ͍ Socket.tcp_server_loop Socket.tcp_server_sockets Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo#listen Socket.new Socket#bind Socket#listen

    Socket.accept_loop Socket#accept_nonblock Socket.tcp Socket.tcp_without_fast_fallback Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo.connect Addrinfo.connect_internal Socket.new Socket#cennect ͷίʔϧελοΫ ͷίʔϧελοΫ
  159. 4PDLFUUDQ4PDLFUUDQ@TFSWFS@MPPQͷେ෦෼͸3VCZ࣮૷ ͜ΕΒͷ࣮૷ࣗମ͕3VCZΛ࢖ͬͨιέοτϓϩάϥϛϯά 3VCZ͓ͬͯ΋͠Ζ͍ Socket.tcp_server_loop Socket.tcp_server_sockets Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo#listen Socket.new Socket#bind

    Socket#listen Socket.accept_loop Socket#accept_nonblock Socket.tcp Socket.tcp_without_fast_fallback Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo.connect Addrinfo.connect_internal Socket.new Socket#cennect ͷίʔϧελοΫ ͷίʔϧελοΫ
  160. ͜ͷͱ͖ιέοτΛ௚઀ૢ࡞͢Δ෦෼͸ɺ࣮ࡍ͸ 3VCZͷ಺෦Ͱ͸$Ͱ࣮૷͞Ε͍ͯΔ Socket.tcp_server_loop Socket.tcp_server_sockets Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo#listen Socket.new Socket#bind Socket#listen

    Socket.accept_loop Socket#accept_nonblock Socket.tcp Socket.tcp_without_fast_fallback Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo.connect Addrinfo.connect_internal Socket.new Socket#cennect 3VCZ͓ͬͯ΋͠Ζ͍ ͷίʔϧελοΫ $࣮૷ $࣮૷ $࣮૷ $࣮૷ $࣮૷ $࣮૷ ͷίʔϧελοΫ
  161. ͦΕΒ͸3VCZͷίʔυͷதͰ͸ 4PDLFUΦϒδΣΫτ΁ͷϝιουݺͼग़͠ͱͯ͠දݱ͞ΕΔ 3VCZ͓ͬͯ΋͠Ζ͍ Socket.tcp Socket.tcp_without_fast_fallback Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo.connect Addrinfo.connect_internal Socket.new

    Socket#cennect ͷίʔϧελοΫ $࣮૷ $࣮૷ Socket.tcp_server_loop Socket.tcp_server_sockets Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo#listen Socket.new Socket#bind Socket#listen Socket.accept_loop Socket#accept_nonblock $࣮૷ $࣮૷ $࣮૷ $࣮૷ ͷίʔϧελοΫ
  162. ೉͍͜͠ͱ͸͢΂ͯ3VCZࣗ਎ͷதʹӅ͞Ε͍ͯΔ Θͨͨͪ͠͸ιέοτΛ ;ͭ͏ͷ3VCZΦϒδΣΫτͱͯ͠ѻ͏͜ͱ͕Ͱ͖Δ 3VCZ͓ͬͯ΋͠Ζ͍ Socket.new socket Socket#connect connect Socket#bind bind

    Socket#listen listen Socket#accept_nonblock accept ɾ ɾ ɾ ɾ ɾ ➡︎  ➡︎  ➡︎  ➡︎  ➡︎ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ