Fukuoka.rb 0x100 回 LT 大会 (#256)
ԘҪඒ࡙ [email protected]'VLVPLBSCYճ-5େձ ࣮NSVCZΈࠐΈମݧ
View Slide
aaॕ'VLVPLBSC։࠵
ࣗݾհԘҪඒ࡙ ͓͍͠(JU)VC!TIJPJNN[email protected]'VLVPLBSCͱ"TBLVTBSCʹ͍ΔNSVCZॳֶऀ࠷ۙͷग़དྷࣄɿࡢѪ༻ͷ؟ڸΛഁյ͠·ͨ͠
NSVCZͱҾ༻IUUQTHJUIVCDPNNSVCZNSVCZXIBUJTNSVCZNSVCZJTUIFMJHIUXFJHIUJNQMFNFOUBUJPOPGUIF3VCZMBOHVBHFDPNQMZJOHUP QBSUPGUIF*40TUBOEBSE*UTTZOUBYJT3VCZYDPNQBUJCMFNSVCZDBOCFMJOLFEBOEFNCFEEFEXJUIJOZPVSBQQMJDBUJPO8FQSPWJEFUIFJOUFSQSFUFSQSPHSBNNSVCZ BOEUIFJOUFSBDUJWFNSVCZTIFMMNJSCBTFYBNQMFT:PVDBOBMTPDPNQJMF3VCZQSPHSBNTJOUPDPNQJMFECZUFDPEFVTJOHUIFNSVCZDPNQJMFSlNSCDz
NSVCZͱҾ༻IUUQTHJUIVCDPNNSVCZNSVCZXIBUJTNSVCZNSVCZJTUIFMJHIUXFJHIUJNQMFNFOUBUJPOPGUIF3VCZMBOHVBHFDPNQMZJOHUP QBSUPGUIF*40TUBOEBSE*UTTZOUBYJT3VCZYDPNQBUJCMFNSVCZDBOCFMJOLFEBOEFNCFEEFEXJUIJOZPVSBQQMJDBUJPO8FQSPWJEFUIFJOUFSQSFUFSQSPHSBNNSVCZ BOEUIFJOUFSBDUJWFNSVCZTIFMMNJSCBTFYBNQMFT:PVDBOBMTPDPNQJMF3VCZQSPHSBNTJOUPDPNQJMFECZUFDPEFVTJOHUIFNSVCZDPNQJMFSlNSCDzʮNSVCZΞϓϦέʔγϣϯʹϦϯΫͯ͠ΈࠐΉ͜ͱ͕Ͱ͖Δʯ[
3VCZͰॻ͔Εͨιʔείʔυͱ$Ͱॻ͔ΕͨΞϓϦέʔγϣϯ͕͋Δͱ͖ɺΞϓϦέʔγϣϯ $3VCZʮNSVCZΛΞϓϦέʔγϣϯʹΈࠐΉʯΠϝʔδ
3VCZͰॻ͔ΕͨॲཧΛΞϓϦέʔγϣϯίʔυʹຒΊࠐΈɺΞϓϦέʔγϣϯ $3VCZʮNSVCZΛΞϓϦέʔγϣϯʹΈࠐΉʯΠϝʔδ3VCZ
ຒΊࠐΜͩॲཧ͝ͱΞϓϦέʔγϣϯΛ࣮ߦ͢ΔΞϓϦέʔγϣϯ $3VCZʮNSVCZΛΞϓϦέʔγϣϯʹΈࠐΉʯΠϝʔδ3VCZ
NSVCZΛ$ΞϓϦέʔγϣϯʹΈࠐΉํ๏͍Ζ͍Ζ&YFDVUJOH3VCZDPEFXJUINSVCZIUUQTNSVCZPSHEPDTBSUJDMFTFYFDVUJOHSVCZDPEFXJUINSVCZIUNM
NSVCZΛ$ΞϓϦέʔγϣϯʹΈࠐΉํ๏͍Ζ͍Ζ ΞϓϦέʔγϣϯίʔυͰNSVCZͷ$"1*Λհͯ͠3VCZͷιʔείʔυΛ࣮ߦ͢Δํ๏3VCZΞϓϦέʔγϣϯ $
NSVCZΛ$ΞϓϦέʔγϣϯʹΈࠐΉํ๏͍Ζ͍Ζ ιʔείʔυ 3VCZΛݩʹ$ͷؔΛ࡞͠ɺΞϓϦέʔγϣϯίʔυ͔ΒJODMVEFͯ͠ݺͼग़͢ํ๏3VCZ ΞϓϦέʔγϣϯ $$$
NSVCZΛ$ΞϓϦέʔγϣϯʹΈࠐΉํ๏͍Ζ͍Ζ ιʔείʔυ 3VCZ͔ΒόΠτίʔυ͕هड़͞ΕͨϑΝΠϧΛ࡞ΞϓϦέʔγϣϯίʔυ͔ΒಡΈࠐΉํ๏ͳͲͳͲʜ3VCZ ΞϓϦέʔγϣϯ $όΠτίʔυ NSCDNSCD
ͬͯΈ·͠ΐ͏
ࠓճΔ͜ͱ͋Δͱ͜Ζʹ$Ͱॻ͔Εͨ5$1Τίʔαʔόʔ͕ΫϥΠΞϯτ αʔόʔ)FMMP)FMMP
ࠓճΔ͜ͱαʔόʔ5$1Τίʔαʔόʔ $ͷ࣮int main(void){// αʔόʔΞυϨεใͷऔಘɹ// ιέοτͷ࡞// ϦΫΤετͷͪड͚// ϦΫΤετͷड͚͚// ϦΫΤετͷಡΈࠐΈ// Ϩεϙϯεͷૹ৴// ιέοτͷഁغreturn 0;}
ࠓճΔ͜ͱint main(void){// αʔόʔΞυϨεใͷऔಘɹ// ιέοτͷ࡞// ϦΫΤετͷͪड͚// ϦΫΤετͷड͚͚// ϦΫΤετͷಡΈࠐΈ// Ϩεϙϯεͷૹ৴// ιέοτͷഁغreturn 0;}⬅︎͜Ε͕ۤखͳͷͰɹ3VCZͰαʔόʔ5$1Τίʔαʔόʔ $ͷ࣮
struct addrinfo server_addr_hints, *server_addr, *server_addr_tmp;int addrinfoerr;memset(&server_addr_hints, 0, sizeof(struct addrinfo));server_addr_hints.ai_family = AF_INET;server_addr_hints.ai_socktype = SOCK_STREAM;server_addr_hints.ai_flags = AI_PASSIVE;if ((addrinfoerr = getaddrinfo(HOST, PORT, &server_addr_hints, &server_addr)) < 0) {gai_strerror(addrinfoerr);}<$ͷ߹>αʔόʔΞυϨεใऔಘ // ศ্ٓ"'@*/&5ʹ͍ͯ͠·͢
struct addrinfo server_addr_hints, *server_addr, *server_addr_tmp;int addrinfoerr;memset(&server_addr_hints, 0, sizeof(struct addrinfo));server_addr_hints.ai_family = AF_INET;server_addr_hints.ai_socktype = SOCK_STREAM;server_addr_hints.ai_flags = AI_PASSIVE;if ((addrinfoerr = getaddrinfo(HOST, PORT, &server_addr_hints, &server_addr)) < 0) {gai_strerror(addrinfoerr);}<$ͷ߹>αʔόʔΞυϨεใऔಘ // ศ্ٓ"'@*/&5ʹ͍ͯ͠·͢ᶃΞυϨεใͷώϯτΛ֨ೲ͢ΔߏମͱɹΞυϨεใΛ֨ೲ͢ΔߏମͷͨΊͷϝϞϦྖҬΛ֬อᶄΞυϨεใͷώϯτΛ֨ೲ͢ΔߏମʹΞυϨεใͷώϯτΛ֨ೲᶅΞυϨεใͷώϯτΛ֨ೲͨ͠ߏମΛར༻ͯ͠ɹ࠷ॳʹݟ͔ͭͬͨΞυϨεใΛΞυϨεใΛ֨ೲ͢Δߏମʹ֨ೲɹ˞͜ͷͱ͖ɺΞυϨεใϦϯΫϦετʹͳ͓ͬͯΓɺɹɹΞυϨεใΛ֨ೲ͢Δߏମଞʹར༻Ͱ͖ΔީิͱͳΔɹɹΞυϨεใͷϙΠϯλΛ͍࣋ͬͯΔ
int listener;for (server_addr_tmp = server_addr;server_addr_tmp;server_addr_tmp = server_addr_tmp->ai_next) {listener = socket(server_addr_tmp->ai_family,server_addr_tmp->ai_socktype,server_addr_tmp->ai_protocol);if (listener < 0) continue;if (bind(listener, server_addr_tmp->ai_addr, server_addr_tmp->ai_addrlen) < 0) {close(listener);continue;}break;}<$ͷ߹>αʔόʔΞυϨεใऔಘ
int listener;for (server_addr_tmp = server_addr;server_addr_tmp;server_addr_tmp = server_addr_tmp->ai_next) {listener = socket(server_addr_tmp->ai_family,server_addr_tmp->ai_socktype,server_addr_tmp->ai_protocol);if (listener < 0) continue;if (bind(listener, server_addr_tmp->ai_addr, server_addr_tmp->ai_addrlen) < 0) {close(listener);continue;}break;}<$ͷ߹>αʔόʔΞυϨεใऔಘ ᶆϦΫΤετΛͪड͚ΔιέοτͷͨΊͷϝϞϦྖҬΛ༻ҙᶇΞυϨεใΛ֨ೲ͢Δߏମ͕࣋ͭϦϯΫΛͨͲͬͯɹ͜ͷߏମͷҰ෦ͷใ͔ΒιέοτΛ࡞͠ɺɹߋʹ͜ͷߏମͷଞͷใ͔Β࣮ࡍʹΞυϨεͱόΠϯυͰ͖Δ͔ࢼΈΔᶈιέοτͷ࡞ͱΞυϨεͷόΠϯυʹޭͨ͠ΒιέοτΛฦ͢
int listener;for (server_addr_tmp = server_addr;server_addr_tmp;server_addr_tmp = server_addr_tmp->ai_next) {listener = socket(server_addr_tmp->ai_family,server_addr_tmp->ai_socktype,server_addr_tmp->ai_protocol);if (listener < 0) continue;if (bind(listener, server_addr_tmp->ai_addr, server_addr_tmp->ai_addrlen) < 0) {close(listener);continue;}break;}<$ͷ߹>αʔόʔΞυϨεใऔಘ ᶆϦΫΤετΛͪड͚ΔιέοτͷͨΊͷϝϞϦྖҬΛ༻ҙᶇΞυϨεใΛ֨ೲ͢Δߏମ͕࣋ͭϦϯΫΛͨͲͬͯɹ͜ͷߏମͷҰ෦ͷใ͔ΒιέοτΛ࡞͠ɺɹߋʹ͜ͷߏମͷଞͷใ͔Β࣮ࡍʹΞυϨεͱόΠϯυͰ͖Δ͔ࢼΈΔᶈιέοτͷ࡞ͱΞυϨεͷόΠϯυʹޭͨ͠ΒιέοτΛฦ͢➡︎͍͠ʜɹΞυϨεͷݕࡧͱιέοτͷ࡞Λಉ࣌ʹߦͬͯɹΞυϨεͷ༗ޮੑΛݕূ͢Δඞཁ͕͋Δ ޮ͕ѱ͍
Addrinfo.getaddrinfo('localhost',12345,Socket::AF_INET,Socket::SOCK_STREAM,nil,Socket::AI_PASSIVE).first<3VCZͷ߹>αʔόʔΞυϨεใऔಘBEESJOGPSC"EESJOGPΦϒδΣΫτΛͭ͘Δ͚ͩʂ"EESJOGPΦϒδΣΫτ͕༗ޮͳΞυϨεใΛ͍࣋ͬͯΔ
Addrinfo.getaddrinfo('localhost',12345,Socket::AF_INET,Socket::SOCK_STREAM,nil,Socket::AI_PASSIVE).first<3VCZͷ߹>αʔόʔΞυϨεใऔಘBEESJOGPSC͜ͷॲཧΛΤίʔαʔόʔͷ෦Ͱ࣮ߦ͠ɺιέοτΛ࡞͢ΔฦΓͱͳΔ"EESJOGPΦϒδΣΫτ ͷΞυϨεใΛར༻ͯ͠
3VCZιʔείʔυΛΤίʔαʔόʔʹΈࠐΉΤίʔαʔόʔʹJODMVEFͯؔ͠ͱ࣮ͯ͠ߦ͢ΔBEESJOGPSC"EESJOGPHFUBEESJOGPΤίʔαʔόʔ $BEESJOGPDBEESJOGP BEESJOGP લड़ͷ3VCZιʔείʔυΛݩʹ$ؔBEESJOGP Λ࡞͠ɺ
NSVCZ͕༻ҙ͍ͯ͠ΔNSCDίϚϯυΛར༻͢Δ͜ͱͰ$ؔBEESJOGP BEESJOGPDΛ؆୯ʹ࡞͢Δ͜ͱ͕Ͱ͖Δ͜͏ͯ͠࡞ͨ͠BEESJOGP ؔΛΤίʔαʔόʔ͔Β࣮ߦ͢Δɹ $ mruby/bin/mrbc -Baddrinfo addrinfo.rb3VCZιʔείʔυ͔Β$ؔΛ࡞͢Δ໊ؔͱιʔεϑΝΠϧΛͯ͠NSCDίϚϯυΛ࣮ߦ
#include #include “addrinfo.c”mrb_state *mrb = mrb_open();// ͜͜ͰΔ͜ͱ// ɹɾBEESJOGP ؔΛݺͼग़͢// ɹɾ"EESJOGPΦϒδΣΫτ͔ΒΞυϨεใΛऔಘ͢Δ// ɾɹऔಘͨ͠ΞυϨεใͰιέοτΛ࡞͢Δmrb_close(mrb);FDIPTFSWFSDBEESJOGPDΛಡΈࠐΉͱɺBEESJOGP ͕ؔར༻Ͱ͖ΔΑ͏ʹͳΔ3VCZιʔείʔυΛΤίʔαʔόʔʹΈࠐΉ
mrb_value addr = mrb_load_irep(mrb, addrinfo);mrb_value domain = mrb_funcall(mrb, addr, "afamily", 0);mrb_value socktype = mrb_funcall(mrb, addr, "socktype", 0);mrb_value protocol = mrb_funcall(mrb, addr, "protocol", 0);mrb_value port = mrb_funcall(mrb, addr, "ip_port", 0);mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0);BEESJOGP ؔΛݺͼग़͢FDIPTFSWFSDBEESJOGP ؔΛ࣮ߦ͢Δͱ"EESJOGPΦϒδΣΫτ͕ฦͬͯ͘Δ
mrb_value addr = mrb_load_irep(mrb, addrinfo);mrb_value domain = mrb_funcall(mrb, addr, "afamily", 0);mrb_value socktype = mrb_funcall(mrb, addr, "socktype", 0);mrb_value protocol = mrb_funcall(mrb, addr, "protocol", 0);mrb_value port = mrb_funcall(mrb, addr, "ip_port", 0);mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0);"EESJOGPΦϒδΣΫτ͔ΒΞυϨεใΛऔಘ͢Δ͜ͷ"EESJOGPΦϒδΣΫτ͔Βιέοτͷ࡞ʹඞཁͳ֤छΞυϨεใΦϒδΣΫτΛऔಘ͢ΔFDIPTFSWFSDυϝΠϯ໊ιέοτλΠϓϓϩτίϧϙʔτ൪߸*1ΞυϨε
mrb_value addr = mrb_load_irep(mrb, addrinfo);mrb_value domain = mrb_funcall(mrb, addr, "afamily", 0);mrb_value socktype = mrb_funcall(mrb, addr, "socktype", 0);mrb_value protocol = mrb_funcall(mrb, addr, "protocol", 0);mrb_value port = mrb_funcall(mrb, addr, "ip_port", 0);mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0);֤ΞυϨεใΦϒδΣΫτ͜ͷޙɺιέοτΛ࡞͢Δ$ؔͷҾͱͯ͠༻͞ΕΔͦͷࡍ3VCZΦϒδΣΫτ͔Β$ͷJOUܕʹม͓ͯ͘͠ඞཁ͕͋ΔFDIPTFSWFSD"EESJOGPΦϒδΣΫτ͔ΒΞυϨεใΛऔಘ͢ΔυϝΠϯ໊ιέοτλΠϓϓϩτίϧϙʔτ൪߸*1ΞυϨε
mrb_value addr = mrb_load_irep(mrb, addrinfo);mrb_value domain = mrb_funcall(mrb, addr, "afamily", 0);mrb_value socktype = mrb_funcall(mrb, addr, "socktype", 0);mrb_value protocol = mrb_funcall(mrb, addr, "protocol", 0);mrb_value port = mrb_funcall(mrb, addr, "ip_port", 0);mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0);FDIPTFSWFSD"EESJOGPΦϒδΣΫτ͔ΒΞυϨεใΛऔಘ͢ΔυϝΠϯ໊ιέοτλΠϓϓϩτίϧϙʔτ൪߸͜͜·Ͱ*OUFHFSΦϒδΣΫτ*OUFHFSΦϒδΣΫτNSVCZͷ$"1*Λར༻͢Δ͜ͱͰ$ͷJOUܕม͢Δ͜ͱ͕Ͱ͖Δ
"EESJOGPΦϒδΣΫτ͔ΒΞυϨεใΛऔಘ͢Δmrb_value addr = mrb_load_irep(mrb, addrinfo);mrb_value domain = mrb_funcall(mrb, addr, "afamily", 0);mrb_value socktype = mrb_funcall(mrb, addr, "socktype", 0);mrb_value protocol = mrb_funcall(mrb, addr, "protocol", 0);mrb_value port = mrb_funcall(mrb, addr, "ip_port", 0);mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0);FDIPTFSWFSD4USJOHΦϒδΣΫτ$ͷJOUܕมͰ͖ͳ͍FHlz*1ΞυϨε4USJOHΦϒδΣΫτ͋Β͔͡Ί4USJOHΦϒδΣΫτ͔Β*OUFHFSΦϒδΣΫτม͢Δඞཁ͋Γ
*1ΞυϨε จࣈྻΛ*1ΞυϨε ʹม͢Δclass Addr2IntRE_IPV4ADDRLIKE = %r{\A(\d+) \. (\d+) \. (\d+) \. (\d+)\z}xdef self.convert(addr)m = RE_IPV4ADDRLIKE.match(addr)octets = m.capturesoctets.inject(0) { |i, s|(n = s.to_i) < 256s.match(/\A0./)i << 8 | n}endendBEESJOUSCࢀߟIUUQTHJUIVCDPNSVCZJQBEESCMPCDDCFBECDDGEMJCJQBEESSC-*1ΞυϨεͷจࣈྻΛʹม͢Δ"EES*OUDPOWFSUϝιουΛ༻ҙ*1"EESFTTϥΠϒϥϦͷ[email protected]ϝιουͷ࣮Λ͓आΓͯ͠ʜ
"EES*OUDPOWFSUϝιουΛ࣮ͨ͠ιʔεϑΝΠϧΛΤίʔαʔόʔ͔ΒಡΈࠐΉNSVCZͷ$"1*Λར༻ͯ͠"EES*OUDPOWFSUϝιουΛݺͼग़͢Τίʔαʔόʔ $BEESJOUSC"EES*OUDPOWFSUΤίʔαʔόʔ͔Β"EES*OUDPOWFSUϝιουΛݺͼग़͢"EES*OUDPOWFSU
"EESJOGPΦϒδΣΫτ͔ΒΞυϨεใΛऔಘ͢Δmrb_value addr = mrb_load_irep(mrb, addrinfo);// …mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0);FILE *addr2int_src = fopen("addr2int.rb", "r");mrb_load_file(mrb, addr2int_src);fclose(addr2int_src);mrb_value addr2int_klass = mrb_obj_value(mrb_class_get(mrb, "Addr2Int"));mrb_value inaddr = mrb_funcall(mrb, addr2int_klass, "convert", 1, address);FDIPTFSWFSDBEESJOUSCιʔεϑΝΠϧΛಡΈࠐΉ"EES*OUDPOWFSUϝιουʹ*1ΞυϨε จࣈྻΛ࣮ͯ͠ߦ
"EESJOGPΦϒδΣΫτ͔ΒΞυϨεใΛऔಘ͢Δmrb_value addr = mrb_load_irep(mrb, addrinfo);// …mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0);FILE *addr2int_src = fopen("addr2int.rb", "r");mrb_load_file(mrb, addr2int_src);fclose(addr2int_src);mrb_value addr2int_klass = mrb_obj_value(mrb_class_get(mrb, "Addr2Int"));mrb_value inaddr = mrb_funcall(mrb, addr2int_klass, "convert", 1, address);FDIPTFSWFSD➡︎*1ΞυϨεΛද͢*OUFHFSΦϒδΣΫτ͕ฦͬͯ͘ΔBEESJOUSCιʔεϑΝΠϧΛಡΈࠐΉ"EES*OUDPOWFSUϝιουʹ*1ΞυϨε จࣈྻΛ࣮ͯ͠ߦ
struct sockaddr_in saddr;saddr.sin_family = mrb_integer(domain);saddr.sin_addr.s_addr = htonl(mrb_integer(inaddr));saddr.sin_port = htons(mrb_integer(port));int listener;if ((listener = socket(mrb_integer(domain), mrb_integer(socktype), mrb_integer(protocol))) < 0) {perror("socket(2)");exit(1);}// …औಘͨ͠ΞυϨεใͰιέοτΛ࡞͢ΔFDIPTFSWFSDΞυϨεใͷ*OUFHFSΦϒδΣΫτΛ$ͷJOUܕʹม͠ɺιέοτΛ࡞ ҎԼɺͦͷଞͷॲཧΛ࣮มιέοτ࡞มมมม ม
αʔόʔ NSVCZͷMJCNSVCZBϑΝΠϧͱϦϯΫͯ͠ΤίʔαʔόʔΛίϯύΠϧΤίʔαʔόʔΛىಈ͢Δ
αʔόʔΫϥΠΞϯτNSVCZͷMJCNSVCZBϑΝΠϧͱϦϯΫͯ͠ΤίʔαʔόʔΛίϯύΠϧΤίʔαʔόʔΛىಈ͢ΔΫϥΠΞϯτ͔ΒαʔόʔϝοηʔδΛૹ৴͢Δ
αʔόʔαʔόʔΫϥΠΞϯτNSVCZͷMJCNSVCZBϑΝΠϧͱϦϯΫͯ͠ΤίʔαʔόʔΛίϯύΠϧΤίʔαʔόʔΛىಈ͢ΔΫϥΠΞϯτ͔ΒαʔόʔϝοηʔδΛૹ৴͢ΔαʔόʔϝοηʔδΛड͚औΓɺͦͷ··ΫϥΠΞϯτฦ৴͢Δ
αʔόʔαʔόʔΫϥΠΞϯτNSVCZͷMJCNSVCZBϑΝΠϧͱϦϯΫͯ͠ΤίʔαʔόʔΛίϯύΠϧΤίʔαʔόʔΛىಈ͢ΔΫϥΠΞϯτ͔ΒαʔόʔϝοηʔδΛૹ৴͢ΔαʔόʔϝοηʔδΛड͚औΓɺͦͷ··ΫϥΠΞϯτฦ৴͢ΔΫϥΠΞϯταʔόʔ͔Βͷฦ৴Λड͚औΔ
ࢀߟਤॻ8FCͰ͑ΔNSVCZγεςϜϓϩάϥϛϯάೖஶऀɿۙ౻Ӊஐ࿕IUUQTXXXDSDPNCPPLEFUBJMೖNSVCZ$͔ΒNSVCZ"1*Λ͍͜ͳ͢ஶऀ:BNBOFLLPIUUQTCPPUIQNKBJUFNT
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ḉ