Pythonã§ã®ãããã¯ãŒã¯ããã°ã©ãã³ã°ã®åãè§£ãæŸã¡ãŸãããããã®å æ¬çãªã¬ã€ãã§ã¯ããœã±ããå®è£ ãTCP/UDPéä¿¡ãå ç¢ã§ã°ããŒãã«ã«ã¢ã¯ã»ã¹å¯èœãªãããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®ãã¹ããã©ã¯ãã£ã¹ãæ¢ããŸãã
Pythonãããã¯ãŒã¯ããã°ã©ãã³ã°ïŒã°ããŒãã«æ¥ç¶ã®ããã®ãœã±ããå®è£ ãè§£ãæãã
ãŸããŸãçžäºæ¥ç¶ãé²ãäžçã«ãããŠããããã¯ãŒã¯ãä»ããŠéä¿¡ããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããèœåã¯ãåãªãå©ç¹ã§ã¯ãªããåºæ¬çãªå¿ èŠæ§ã§ãã倧éžããŸããããªã¢ã«ã¿ã€ã ã³ã©ãã¬ãŒã·ã§ã³ããŒã«ããã°ããŒãã«ãªããŒã¿åæãµãŒãã¹ãŸã§ãçŸä»£ã®ããããããžã¿ã«ã€ã³ã¿ã©ã¯ã·ã§ã³ã®åºç€ãšãªã£ãŠããã®ããããã¯ãŒã¯ããã°ã©ãã³ã°ã§ãããã®è€éãªéä¿¡ç¶²ã®äžå¿ã«ã¯ãããœã±ããããšããæŠå¿µããããŸããPythonã¯ããã®æŽç·Žãããæ§æãšåŒ·åãªæšæºã©ã€ãã©ãªã«ããããã®é åãžã®éåžžã«ã¢ã¯ã»ã¹ããããã²ãŒããŠã§ã€ãæäŸããäžçäžã®éçºè ãæ¯èŒçç°¡åã«æŽç·Žããããããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ãäœæããããšãå¯èœã«ããŸãã
ãã®å æ¬çãªã¬ã€ãã§ã¯ãPythonã®`socket`ã¢ãžã¥ãŒã«ãæ·±ãæãäžããTCPãšUDPã®äž¡ãããã³ã«ã䜿çšããŠå ç¢ãªãããã¯ãŒã¯éä¿¡ãå®è£ ããæ¹æ³ãæ¢ããŸããçè§£ãæ·±ãããçç·Žéçºè ã§ããããšãåããŠã®ãããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ãããåå¿è ã§ããããšããã®èšäºã¯çã«ã°ããŒãã«ãªãªãŒãã£ãšã³ã¹åãã®Pythonãœã±ããããã°ã©ãã³ã°ãç¿åŸããããã®ç¥èãšå®çšçãªäŸãæäŸããŸãã
ãããã¯ãŒã¯éä¿¡ã®åºæ¬ãçè§£ãã
Pythonã®`socket`ã¢ãžã¥ãŒã«ã®è©³çްã«å ¥ãåã«ããã¹ãŠã®ãããã¯ãŒã¯éä¿¡ãæ¯ããåºç€æŠå¿µãææ¡ããããšãéèŠã§ãããããã®åºæ¬ãçè§£ããããšã§ããœã±ãããã©ã®ããã«æ©èœãããªãããæ©èœããã®ãã«ã€ããŠãããæç¢ºãªæèãåŸãããŸãã
OSIã¢ãã«ãšTCP/IPã¹ã¿ã㯠â ç°¡åãªæŠèŠ
ãããã¯ãŒã¯éä¿¡ã¯éåžžãéå±€åã¢ãã«ãéããŠæŠå¿µåãããŸããæãèåãªã®ã¯OSIïŒOpen Systems InterconnectionïŒã¢ãã«ãšTCP/IPã¹ã¿ãã¯ã§ããOSIã¢ãã«ã¯ããçè«çãª7å±€ã¢ãããŒããæäŸããŸãããTCP/IPã¹ã¿ãã¯ã¯ã€ã³ã¿ãŒããããåããå®çšçãªå®è£ ã§ãã
- ã¢ããªã±ãŒã·ã§ã³å±€: ããã«ã¯ãããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ïŒãŠã§ããã©ãŠã¶ãé»åã¡ãŒã«ã¯ã©ã€ã¢ã³ããFTPã¯ã©ã€ã¢ã³ããªã©ïŒãååšãããŠãŒã¶ãŒããŒã¿ãšçŽæ¥å¯Ÿè©±ããŸããHTTPãFTPãSMTPãDNSãªã©ã®ãããã³ã«ãããã«å±ããŸãã
- ãã©ã³ã¹ããŒãå±€: ãã®å±€ã¯ã¢ããªã±ãŒã·ã§ã³éã®ãšã³ãããŒãšã³ãéä¿¡ãåŠçããŸããã¢ããªã±ãŒã·ã§ã³ããŒã¿ãã»ã°ã¡ã³ãã«åå²ãããã®ä¿¡é Œæ§ã®é«ãããŸãã¯ä¿¡é Œæ§ã®äœãé ä¿¡ã管çããŸããããã§ã®äž»èŠãª2ã€ã®ãããã³ã«ã¯ãTCPïŒTransmission Control ProtocolïŒãšUDPïŒUser Datagram ProtocolïŒã§ãã
- ã€ã³ã¿ãŒããã/ãããã¯ãŒã¯å±€: è«çã¢ãã¬ã¹æå®ïŒIPã¢ãã¬ã¹ïŒãšãç°ãªããããã¯ãŒã¯éã§ã®ãã±ããã®ã«ãŒãã£ã³ã°ãæ åœããŸããIPv4ãšIPv6ãããã§ã®äž»èŠãªãããã³ã«ã§ãã
- ãªã³ã¯/ããŒã¿ãªã³ã¯å±€: ç©çã¢ãã¬ã¹æå®ïŒMACã¢ãã¬ã¹ïŒãšãããŒã«ã«ãããã¯ãŒã¯ã»ã°ã¡ã³ãå ã§ã®ããŒã¿éä¿¡ãæ±ããŸãã
- ç©çå±€: ã±ãŒãã«ãã³ãã¯ã¿ã黿°ä¿¡å·ãªã©ããããã¯ãŒã¯ã®ç©ççç¹æ§ãå®çŸ©ããŸãã
ãœã±ããã䜿çšããç§ãã¡ã®ç®çã§ã¯ãäž»ã«ãã©ã³ã¹ããŒãå±€ãšãããã¯ãŒã¯å±€ãšå¯Ÿè©±ããã¢ããªã±ãŒã·ã§ã³ãIPã¢ãã¬ã¹ãšããŒããä»ããŠTCPãŸãã¯UDPãã©ã®ããã«äœ¿çšããŠéä¿¡ããããäžå¿ã«æ±ããŸãã
IPã¢ãã¬ã¹ãšããŒãïŒããžã¿ã«ã®åº§æš
æçŽãéãããšãæ³åããŠã¿ãŠãã ãããæ£ãã建ç©ã«å±ããããã®äœæãšããã®å»ºç©å ã®æ£ããåå人ã«å±ããããã®ç¹å®ã®éšå±çªå·ã®äž¡æ¹ãå¿ èŠã§ãããããã¯ãŒã¯ããã°ã©ãã³ã°ã§ã¯ãIPã¢ãã¬ã¹ãšããŒãçªå·ãåæ§ã®åœ¹å²ãæãããŸãã
-
IPã¢ãã¬ã¹ïŒInternet Protocol AddressïŒ: ããã¯ãéä¿¡ã«ã€ã³ã¿ãŒããããããã³ã«ã䜿çšããã³ã³ãã¥ãŒã¿ãããã¯ãŒã¯ã«æ¥ç¶ãããåããã€ã¹ã«å²ãåœãŠãããäžæã®æ°å€ã©ãã«ã§ãããããã¯ãŒã¯äžã®ç¹å®ã®ãã·ã³ãèå¥ããŸãã
- IPv4: ããå€ããããäžè¬çãªããŒãžã§ã³ã§ããããã§åºåããã4ã€ã®æ°å€ã»ãããšããŠè¡šçŸãããŸãïŒäŸïŒ`192.168.1.1`ïŒãçŽ43åã®äžæã®ã¢ãã¬ã¹ããµããŒãããŸãã
- IPv6: IPv4ã¢ãã¬ã¹ã®æ¯æžã«å¯Ÿå¿ããããã«èšèšãããæ°ããããŒãžã§ã³ã§ããã³ãã³ã§åºåããã8ã°ã«ãŒãã®4æ¡ã®16鲿°ã§è¡šçŸãããŸãïŒäŸïŒ`2001:0db8:85a3:0000:0000:8a2e:0370:7334`ïŒãIPv6ã¯ãã€ã³ã¿ãŒãããã®ã°ããŒãã«ãªæ¡å€§ãšã倿§ãªå°åã§ã®IoTããã€ã¹ã®æ®åã«ãšã£ãŠäžå¯æ¬ ãªãã¯ããã«åºå€§ãªã¢ãã¬ã¹ç©ºéãæäŸããŸããPythonã®`socket`ã¢ãžã¥ãŒã«ã¯IPv4ãšIPv6ã®äž¡æ¹ãå®å šã«ãµããŒãããŠãããéçºè ã¯å°æ¥æ§ã®ããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã
-
ããŒãçªå·: IPã¢ãã¬ã¹ãç¹å®ã®ãã·ã³ãèå¥ããã®ã«å¯ŸããããŒãçªå·ã¯ãã®ãã·ã³äžã§å®è¡ãããŠããç¹å®ã®ã¢ããªã±ãŒã·ã§ã³ãŸãã¯ãµãŒãã¹ãèå¥ããŸãã0ãã65535ãŸã§ã®16ãããã®æ°å€ã§ãã
- ãŠã§ã«ããŠã³ããŒãïŒ0-1023ïŒ: äžè¬çãªãµãŒãã¹ã®ããã«äºçŽãããŠããŸãïŒäŸïŒHTTPã¯ããŒã80ãHTTPSã¯443ãFTPã¯21ãSSHã¯22ãDNSã¯53ã䜿çšããŸãïŒããããã¯ã°ããŒãã«ã«æšæºåãããŠããŸãã
- ç»é²æžã¿ããŒãïŒ1024-49151ïŒ: ç¹å®ã®ã¢ããªã±ãŒã·ã§ã³ã®ããã«çµç¹ã«ãã£ãŠç»é²ã§ããŸãã
- åç/ãã©ã€ããŒãããŒãïŒ49152-65535ïŒ: ç§ç䜿çšããã³äžæçãªæ¥ç¶ã®ããã«å©çšå¯èœã§ãã
ãããã³ã«ïŒTCP vs. UDP â é©åãªã¢ãããŒãã®éžæ
ãã©ã³ã¹ããŒãå±€ã§ã¯ãTCPãšUDPã®ã©ã¡ããéžæãããããã¢ããªã±ãŒã·ã§ã³ã®éä¿¡æ¹æ³ã«å€§ãã圱é¿ããŸããããããç°ãªãçš®é¡ã®ãããã¯ãŒã¯ã€ã³ã¿ã©ã¯ã·ã§ã³ã«é©ããç¬ç¹ã®ç¹æ§ãæã£ãŠããŸãã
TCPïŒTransmission Control ProtocolïŒ
TCPã¯ã³ãã¯ã·ã§ã³æåã®ä¿¡é Œæ§ã®é«ããããã³ã«ã§ããããŒã¿äº€æãè¡ãåã«ãã¯ã©ã€ã¢ã³ããšãµãŒããŒéã§æ¥ç¶ïŒãã°ãã°ãã¹ãªãŒãŠã§ã€ãã³ãã·ã§ã€ã¯ããšåŒã°ããïŒã確ç«ããå¿ èŠããããŸããäžåºŠç¢ºç«ããããšãTCPã¯ä»¥äžãä¿èšŒããŸãã
- é åºä¿èšŒé ä¿¡: ããŒã¿ã»ã°ã¡ã³ãã¯éä¿¡ãããé åºã§å°çããŸãã
- ãšã©ãŒãã§ãã¯: ããŒã¿ç Žæãæ€åºãããåŠçãããŸãã
- åéä¿¡: æå€±ããããŒã¿ã»ã°ã¡ã³ãã¯åéä¿¡ãããŸãã
- ãããŒå¶åŸ¡: éãéä¿¡è ãé ãåä¿¡è ãå§åããã®ãé²ããŸãã
- 茻茳å¶åŸ¡: ãããã¯ãŒã¯ã®èŒ»èŒ³ãé²ãã®ã«åœ¹ç«ã¡ãŸãã
ãŠãŒã¹ã±ãŒã¹: ãã®ä¿¡é Œæ§ã®ãããTCPã¯ããŒã¿ã®æŽåæ§ãšé åºãæåªå ãããã¢ããªã±ãŒã·ã§ã³ã«æé©ã§ããäŸãšããŠã¯ä»¥äžãæããããŸãã
- ãŠã§ããã©ãŠãžã³ã°ïŒHTTP/HTTPSïŒ
- ãã¡ã€ã«è»¢éïŒFTPïŒ
- é»åã¡ãŒã«ïŒSMTPãPOP3ãIMAPïŒ
- ã»ãã¥ã¢ã·ã§ã«ïŒSSHïŒ
- ããŒã¿ããŒã¹æ¥ç¶
UDPïŒUser Datagram ProtocolïŒ
UDPã¯ã³ãã¯ã·ã§ã³ã¬ã¹ã®ä¿¡é Œæ§ã®äœããããã³ã«ã§ããããŒã¿ãéä¿¡ããåã«æ¥ç¶ã確ç«ãããé ä¿¡ãé åºããšã©ãŒãã§ãã¯ãä¿èšŒããŸãããããŒã¿ã¯åå¥ã®ãã±ããïŒããŒã¿ã°ã©ã ïŒãšããŠéä¿¡ãããåä¿¡è ããã®ç¢ºèªå¿çã¯ãããŸããã
ãŠãŒã¹ã±ãŒã¹: UDPã¯ãªãŒããŒãããããªããããTCPãããã¯ããã«é«éã§ããé床ãä¿èšŒãããé ä¿¡ãããéèŠã§ããããã¢ããªã±ãŒã·ã§ã³å±€èªäœãä¿¡é Œæ§ãåŠçããã¢ããªã±ãŒã·ã§ã³ã«å¥œãŸããŸããäŸãšããŠã¯ä»¥äžãæããããŸãã
- ãã¡ã€ã³ããŒã ã·ã¹ãã ïŒDNSïŒã«ãã¯ã¢ãã
- ã¹ããªãŒãã³ã°ã¡ãã£ã¢ïŒãããªããã³ãªãŒãã£ãªïŒ
- ãªã³ã©ã€ã³ã²ãŒã
- ãã€ã¹ãªãŒããŒIPïŒVoIPïŒ
- ãããã¯ãŒã¯ç®¡çãããã³ã«ïŒSNMPïŒ
- äžéšã®IoTã»ã³ãµãŒããŒã¿éä¿¡
TCPãšUDPã®éžæã¯ãç¹ã«ãã±ãããã¹ãšé å»¶ã倧ããå€åãã倿§ãªã°ããŒãã«ãããã¯ãŒã¯æ¡ä»¶ãèæ ®ããå Žåããããããããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠåºæ¬çãªã¢ãŒããã¯ãã£äžã®æ±ºå®ãšãªããŸãã
Pythonã®`socket`ã¢ãžã¥ãŒã«ïŒãããã¯ãŒã¯ãžã®ã²ãŒããŠã§ã€
Pythonã®çµã¿èŸŒã¿`socket`ã¢ãžã¥ãŒã«ã¯ãåºç€ãšãªããããã¯ãŒã¯ãœã±ããã€ã³ã¿ãŒãã§ãŒã¹ãžã®çŽæ¥ã¢ã¯ã»ã¹ãæäŸããã«ã¹ã¿ã ã¯ã©ã€ã¢ã³ãããã³ãµãŒããŒã¢ããªã±ãŒã·ã§ã³ã®äœæãå¯èœã«ããŸããæšæºã®Berkeleyãœã±ããAPIã«å¯æ¥ã«æºæ ããŠãããããC/C++ãããã¯ãŒã¯ããã°ã©ãã³ã°ã®çµéšè ã«ã¯éŠŽæã¿æ·±ããåæã«Pythonããã䜿ãããããå ŒãåããŠããŸãã
ãœã±ãããšã¯ïŒ
ãœã±ããã¯éä¿¡ã®ãšã³ããã€ã³ããšããŠæ©èœããŸããããã¯ãã¢ããªã±ãŒã·ã§ã³ããããã¯ãŒã¯ãä»ããŠããŒã¿ãéåä¿¡ã§ããããã«ããæœè±¡åã§ããæŠå¿µçã«ã¯ãé»è©±åç·ãéµäŸ¿ã¢ãã¬ã¹ã®ããã«ãã¡ãã»ãŒãžãéåä¿¡ã§ããåæ¹åéä¿¡ãã£ãã«ã®äžç«¯ãšèããããšãã§ããŸããåãœã±ããã¯ç¹å®ã®IPã¢ãã¬ã¹ãšããŒãçªå·ã«ãã€ã³ããããŸãã
ã³ã¢ãœã±ãã颿°ãšå±æ§
ãœã±ãããäœæããã³ç®¡çããã«ã¯ãäž»ã«`socket.socket()`ã³ã³ã¹ãã©ã¯ã¿ãšãã®ã¡ãœããã䜿çšããŸãã
socket.socket(family, type, proto=0): ããã¯æ°ãããœã±ãããªããžã§ã¯ããäœæããããã«äœ¿çšãããã³ã³ã¹ãã©ã¯ã¿ã§ããfamily:ã¢ãã¬ã¹ãã¡ããªãŒãæå®ããŸããäžè¬çãªå€ã¯IPv4çšã®`socket.AF_INET`ãšIPv6çšã®`socket.AF_INET6`ã§ãã`socket.AF_UNIX`ã¯åäžãã·ã³äžã®ããã»ã¹ééä¿¡çšã§ããtype:ãœã±ããã¿ã€ããæå®ããŸãã`socket.SOCK_STREAM`ã¯TCPçšïŒã³ãã¯ã·ã§ã³æåãä¿¡é Œæ§ããïŒã§ãã`socket.SOCK_DGRAM`ã¯UDPçšïŒã³ãã¯ã·ã§ã³ã¬ã¹ãä¿¡é Œæ§ãªãïŒã§ããproto:ãããã³ã«çªå·ã§ããéåžžã¯0ã§ãã·ã¹ãã ããã¡ããªãŒãšã¿ã€ãã«åºã¥ããŠé©åãªãããã³ã«ãéžæã§ããããã«ããŸãã
bind(address): ããŒã«ã«ãã·ã³äžã®ç¹å®ã®ãããã¯ãŒã¯ã€ã³ã¿ãŒãã§ãŒã¹ãšããŒãçªå·ã«ãœã±ãããé¢é£ä»ããŸãã`address`ã¯IPv4ã®å Žåã¯ã¿ãã«`(host, port)`ãIPv6ã®å Žåã¯`(host, port, flowinfo, scopeid)`ã§ãã`host`ã¯IPã¢ãã¬ã¹ïŒäŸïŒããŒã«ã«ãã¹ãã®`'127.0.0.1'`ïŒãŸãã¯ãã¹ãåã§ãã`''`ãŸãã¯`'0.0.0.0'`ïŒIPv4ã®å ŽåïŒãŸãã¯`'::'`ïŒIPv6ã®å ŽåïŒã䜿çšãããšããœã±ããã¯å©çšå¯èœãªãã¹ãŠã®ãããã¯ãŒã¯ã€ã³ã¿ãŒãã§ãŒã¹ã§ãªãã¹ã³ãããããã¯ãŒã¯äžã®ã©ã®ãã·ã³ãããã¢ã¯ã»ã¹å¯èœã«ãªããŸããããã¯ã°ããŒãã«ã«ã¢ã¯ã»ã¹å¯èœãªãµãŒããŒã«ãšã£ãŠéèŠãªèæ ®äºé ã§ããlisten(backlog): ãµãŒããŒãœã±ããããªã¹ãã³ã°ã¢ãŒãã«ããçä¿¡ã¯ã©ã€ã¢ã³ãæ¥ç¶ãåãå ¥ããããããã«ããŸãã`backlog`ã¯ãã·ã¹ãã ããã¥ãŒã«å ¥ããä¿çäžã®æ¥ç¶ã®æå€§æ°ãæå®ããŸãããã¥ãŒããã£ã±ãã®å Žåãæ°ããæ¥ç¶ã¯æåŠãããå¯èœæ§ããããŸããaccept(): ãµãŒããŒãœã±ããïŒTCPïŒã®å Žåããã®ã¡ãœããã¯ã¯ã©ã€ã¢ã³ããæ¥ç¶ãããŸã§å®è¡ããããã¯ããŸããã¯ã©ã€ã¢ã³ããæ¥ç¶ãããšããã®ã¯ã©ã€ã¢ã³ããžã®æ¥ç¶ãè¡šãæ°ãããœã±ãããªããžã§ã¯ããšãã¯ã©ã€ã¢ã³ãã®ã¢ãã¬ã¹ãè¿ããŸããå ã®ãµãŒããŒãœã±ããã¯æ°ããæ¥ç¶ããªãã¹ã³ãç¶ããŸããconnect(address): ã¯ã©ã€ã¢ã³ããœã±ããïŒTCPïŒã®å Žåããã®ã¡ãœããã¯æå®ããã`address`ã®ãªã¢ãŒããœã±ããïŒãµãŒããŒïŒãžã®æ¥ç¶ãã¢ã¯ãã£ãã«ç¢ºç«ããŸããsend(data): æ¥ç¶ããããœã±ããïŒTCPïŒã«`data`ãéä¿¡ããŸããéä¿¡ããããã€ãæ°ãè¿ããŸããrecv(buffersize): æ¥ç¶ããããœã±ããïŒTCPïŒãã`data`ãåä¿¡ããŸãã`buffersize`ã¯äžåºŠã«åä¿¡ããããŒã¿ã®æå€§éãæå®ããŸããåä¿¡ãããã€ãæ°ãè¿ããŸããsendall(data): `send()`ã«äŒŒãŠããŸããããã¹ãŠã®ãã€ããéä¿¡ãããããšã©ãŒãçºçãããŸã§ã`send()`ãç¹°ãè¿ãåŒã³åºãããšã§ãæäŸããã`data`ã®ãã¹ãŠãéä¿¡ããããšããŸããããã¯å®å šãªããŒã¿éä¿¡ãä¿èšŒããããã«TCPã§äžè¬çã«æšå¥šãããŸããsendto(data, address): ç¹å®ã®`address`ã«`data`ãéä¿¡ããŸãïŒUDPïŒãããã¯ãäºå確ç«ãããæ¥ç¶ããªããããã³ãã¯ã·ã§ã³ã¬ã¹ãœã±ããã§äœ¿çšãããŸããrecvfrom(buffersize): UDPãœã±ãããã`data`ãåä¿¡ããŸãã`(data, address)`ã®ã¿ãã«ãè¿ãã`address`ã¯éä¿¡è ã®ã¢ãã¬ã¹ã§ããclose(): ãœã±ãããéããŸããä¿çäžã®ããŒã¿ã¯ãã¹ãŠå€±ãããå¯èœæ§ããããŸããã·ã¹ãã ãªãœãŒã¹ãè§£æŸãããããäžèŠã«ãªã£ããœã±ããã¯éããããšãéèŠã§ããsettimeout(timeout): ããããã³ã°ãœã±ããæäœïŒ`accept()`ã`connect()`ã`recv()`ã`send()`ãªã©ïŒã«ã¿ã€ã ã¢ãŠããèšå®ããŸããæäœã`timeout`æéãè¶ ãããšã`socket.timeout`äŸå€ãçºçããŸããå€`0`ã¯éããããã³ã°ãæå³ãã`None`ã¯ç¡æéã®ããããã³ã°ãæå³ããŸããããã¯ãç¹ã«ãããã¯ãŒã¯ã®ä¿¡é Œæ§ãšé å»¶ãå€åããç°å¢ã§ã®å¿çæ§ã®é«ãã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠäžå¯æ¬ ã§ããsetsockopt(level, optname, value): ããŸããŸãªãœã±ãããªãã·ã§ã³ãèšå®ããããã«äœ¿çšãããŸããäžè¬çãªäœ¿çšæ³ã¯ã`sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)`ã§ããµãŒããŒãæè¿éããããããŒãã«ããã«åãã€ã³ãã§ããããã«ããããšã§ããããã¯ãã°ããŒãã«ã«åæ£ããããµãŒãã¹ã§è¿ éãªåèµ·åãäžè¬çã§ããéçºããã³ãããã€äžã«åœ¹ç«ã¡ãŸãã
åºæ¬çãªTCPã¯ã©ã€ã¢ã³ãã»ãµãŒããŒã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯
ã¯ã©ã€ã¢ã³ãããµãŒããŒã«ã¡ãã»ãŒãžãéä¿¡ãããµãŒããŒãããããšã³ãŒããã¯ããç°¡åãªTCPã¯ã©ã€ã¢ã³ãã»ãµãŒããŒã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããŸãããããã®äŸã¯ãæ°å€ãã®ãããã¯ãŒã¯å¯Ÿå¿ã¢ããªã±ãŒã·ã§ã³ã®åºç€ãšãªããŸãã
TCPãµãŒããŒã®å®è£
TCPãµãŒããŒã¯éåžžã以äžã®æé ãå®è¡ããŸãã
- ãœã±ãããªããžã§ã¯ããäœæããŸãã
- ãœã±ãããç¹å®ã®IPã¢ãã¬ã¹ïŒIPãšããŒãïŒã«ãã€ã³ãããŸãã
- ãœã±ããããªã¹ãã³ã°ã¢ãŒãã«ããŸãã
- ã¯ã©ã€ã¢ã³ãããã®çä¿¡æ¥ç¶ãåãå ¥ããŸããããã«ãããåã¯ã©ã€ã¢ã³ãçšã«æ°ãããœã±ãããäœæãããŸãã
- ã¯ã©ã€ã¢ã³ãããããŒã¿ãåä¿¡ããåŠçããŠå¿çãéä¿¡ããŸãã
- ã¯ã©ã€ã¢ã³ãæ¥ç¶ãéããŸãã
以äžã¯ãç°¡åãªTCPãšã³ãŒãµãŒããŒã®Pythonã³ãŒãã§ãã
import socket
import threading
HOST = '0.0.0.0' # Listen on all available network interfaces
PORT = 65432 # Port to listen on (non-privileged ports are > 1023)
def handle_client(conn, addr):
"""Handle communication with a connected client."""
print(f"Connected by {addr}")
try:
while True:
data = conn.recv(1024) # Receive up to 1024 bytes
if not data: # Client disconnected
print(f"Client {addr} disconnected.")
break
print(f"Received from {addr}: {data.decode()}")
# Echo back the received data
conn.sendall(data)
except ConnectionResetError:
print(f"Client {addr} forcibly closed the connection.")
except Exception as e:
print(f"Error handling client {addr}: {e}")
finally:
conn.close() # Ensure the connection is closed
print(f"Connection with {addr} closed.")
def run_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
# Allow the port to be reused immediately after the server closes
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen()
print(f"Server listening on {HOST}:{PORT}...")
while True:
conn, addr = s.accept() # Blocks until a client connects
# For handling multiple clients concurrently, we use threading
client_thread = threading.Thread(target=handle_client, args=(conn, addr))
client_thread.start()
if __name__ == "__main__":
run_server()
ãµãŒããŒã³ãŒãã®èª¬æïŒ
HOST = '0.0.0.0': ãã®ç¹æ®ãªIPã¢ãã¬ã¹ã¯ããµãŒããŒããã·ã³äžã®ä»»æã®ãããã¯ãŒã¯ã€ã³ã¿ãŒãã§ãŒã¹ããã®æ¥ç¶ããªãã¹ã³ããããšãæå³ããŸããããã¯ãããŒã«ã«ãã¹ãã ãã§ãªããä»ã®ãã·ã³ãã€ã³ã¿ãŒãããããã¢ã¯ã»ã¹ã§ããããã«ãããµãŒããŒã«ãšã£ãŠéèŠã§ããPORT = 65432: ããç¥ããããµãŒãã¹ãšã®ç«¶åãé¿ããããã«ãé«çªå·ã®ããŒããéžæãããŠããŸããå€éšã¢ã¯ã»ã¹çšã«ããã®ããŒããã·ã¹ãã ã®ãã¡ã€ã¢ãŠã©ãŒã«ã§éããŠããããšã確èªããŠãã ãããwith socket.socket(...) as s:: ããã¯ã³ã³ããã¹ããããŒãžã£ãŒã䜿çšããŠããããšã©ãŒãçºçããå Žåã§ããããã¯ãçµäºãããšãœã±ãããèªåçã«éããããããšãä¿èšŒããŸãã`socket.AF_INET`ã¯IPv4ãæå®ãã`socket.SOCK_STREAM`ã¯TCPãæå®ããŸããs.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1): ãã®ãªãã·ã§ã³ã¯ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ããŒã«ã«ã¢ãã¬ã¹ã®åå©çšãèš±å¯ããããæç€ºãããµãŒããŒãæè¿éããããããŒãã§ãã£ãŠãåãããŒãã«ãã€ã³ãã§ããããã«ããŸããããã¯éçºäžããã³è¿ éãªãµãŒããŒåèµ·åãå¿ èŠãªã°ããŒãã«åæ£ãµãŒãã¹ã«ãšã£ãŠéåžžã«è²Žéã§ããs.bind((HOST, PORT)): ãœã±ãã`s`ãæå®ãããIPã¢ãã¬ã¹ãšããŒãã«é¢é£ä»ããŸããs.listen(): ãµãŒããŒãœã±ããããªã¹ãã³ã°ã¢ãŒãã«ããŸããããã©ã«ãã§ã¯ãPythonã®listen backlogã¯5ã§ããå¯èœæ§ããããããã¯æ°ããæ¥ç¶ãæåŠããåã«æå€§5ã€ã®ä¿çäžã®æ¥ç¶ããã¥ãŒã«å ¥ããããšãã§ããããšãæå³ããŸããconn, addr = s.accept(): ããã¯ããããã³ã°ã³ãŒã«ã§ãããµãŒããŒã¯ã¯ã©ã€ã¢ã³ããæ¥ç¶ã詊ã¿ããŸã§ããã§åŸ æ©ããŸããæ¥ç¶ã確ç«ããããšã`accept()`ã¯ãã®ç¹å®ã®ã¯ã©ã€ã¢ã³ããšã®éä¿¡å°çšã®æ°ãããœã±ãããªããžã§ã¯ãïŒ`conn`ïŒãšãã¯ã©ã€ã¢ã³ãã®IPã¢ãã¬ã¹ãšããŒããå«ãã¿ãã«ã§ãã`addr`ãè¿ããŸããthreading.Thread(target=handle_client, args=(conn, addr)).start(): è€æ°ã®ã¯ã©ã€ã¢ã³ããåæã«åŠçããããïŒããã¯å®éã®ãµãŒããŒã§ã¯äžè¬çã§ãïŒãåã¯ã©ã€ã¢ã³ãæ¥ç¶ã«å¯ŸããŠæ°ããã¹ã¬ãããèµ·åããŸããããã«ãããã¡ã€ã³ãµãŒããŒã«ãŒãã¯æ¢åã®ã¯ã©ã€ã¢ã³ããçµäºããã®ãåŸ ã€ããšãªããæ°ããã¯ã©ã€ã¢ã³ããåãå ¥ãç¶ããããšãã§ããŸããéåžžã«é«ãããã©ãŒãã³ã¹ãéåžžã«å€æ°ã®åææ¥ç¶ã®å Žåã`asyncio`ã䜿çšããéåæããã°ã©ãã³ã°ãããã¹ã±ãŒã©ãã«ãªã¢ãããŒããšãªããŸããconn.recv(1024): ã¯ã©ã€ã¢ã³ãããéä¿¡ãããæå€§1024ãã€ãã®ããŒã¿ãèªã¿åããŸãã`recv()`ã空ã®`bytes`ãªããžã§ã¯ãïŒ`if not data:`ïŒãè¿ãç¶æ³ãåŠçããããšãéèŠã§ããããã¯ã¯ã©ã€ã¢ã³ããæ¥ç¶ã®èªãã®åŽãæ£åžžã«éããããšã瀺ããŸããdata.decode(): ãããã¯ãŒã¯ããŒã¿ã¯éåžžãã€ãã§ããããã¹ããšããŠæ±ãã«ã¯ããã³ãŒãããå¿ èŠããããŸãïŒäŸïŒUTF-8ã䜿çšïŒãconn.sendall(data): åä¿¡ããããŒã¿ãã¯ã©ã€ã¢ã³ãã«éãè¿ããŸãã`sendall()`ã¯ãã¹ãŠã®ãã€ããéä¿¡ãããããšãä¿èšŒããŸãã- ãšã©ãŒåŠç: å ç¢ãªãããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ã«ã¯`try-except`ãããã¯ãå«ããããšãäžå¯æ¬ ã§ãã`ConnectionResetError`ã¯ãã¯ã©ã€ã¢ã³ããé©åãªã·ã£ããããŠã³ãªãã«æ¥ç¶ã匷å¶çã«éããå ŽåïŒäŸïŒé»æºåªå€±ãã¢ããªã±ãŒã·ã§ã³ã¯ã©ãã·ã¥ïŒã«ããçºçããŸãã
TCPã¯ã©ã€ã¢ã³ãã®å®è£
TCPã¯ã©ã€ã¢ã³ãã¯éåžžã以äžã®æé ãå®è¡ããŸãã
- ãœã±ãããªããžã§ã¯ããäœæããŸãã
- ãµãŒããŒã®IPã¢ãã¬ã¹ïŒIPãšããŒãïŒã«æ¥ç¶ããŸãã
- ãµãŒããŒã«ããŒã¿ãéä¿¡ããŸãã
- ãµãŒããŒã®å¿çãåä¿¡ããŸãã
- æ¥ç¶ãéããŸãã
以äžã¯ãç°¡åãªTCPãšã³ãŒã¯ã©ã€ã¢ã³ãã®Pythonã³ãŒãã§ãã
import socket
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 65432 # The port used by the server
def run_client():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
try:
s.connect((HOST, PORT))
message = input("Enter message to send (type 'quit' to exit): ")
while message.lower() != 'quit':
s.sendall(message.encode())
data = s.recv(1024)
print(f"Received from server: {data.decode()}")
message = input("Enter message to send (type 'quit' to exit): ")
except ConnectionRefusedError:
print(f"Connection to {HOST}:{PORT} refused. Is the server running?")
except socket.timeout:
print("Connection timed out.")
except Exception as e:
print(f"An error occurred: {e}")
finally:
s.close()
print("Connection closed.")
if __name__ == "__main__":
run_client()
ã¯ã©ã€ã¢ã³ãã³ãŒãã®èª¬æïŒ
HOST = '127.0.0.1': åããã·ã³ã§ãã¹ãããããã«ã`127.0.0.1`ïŒããŒã«ã«ãã¹ãïŒã䜿çšãããŸãããµãŒããŒãç°ãªããã·ã³ïŒäŸïŒå¥ã®åœã®ãªã¢ãŒãããŒã¿ã»ã³ã¿ãŒïŒã«ããå Žåã¯ãããããã®ãããªãã¯IPã¢ãã¬ã¹ãŸãã¯ãã¹ãåã«çœ®ãæããŸããs.connect((HOST, PORT)): ãµãŒããŒãžã®æ¥ç¶ã確ç«ããããšããŸããããã¯ããããã³ã°ã³ãŒã«ã§ããmessage.encode(): éä¿¡ããåã«ãæååã¡ãã»ãŒãžããã€ãã«ãšã³ã³ãŒãããå¿ èŠããããŸãïŒäŸïŒUTF-8ã䜿çšïŒã- å ¥åã«ãŒã: ã¯ã©ã€ã¢ã³ãã¯ããŠãŒã¶ãŒããquitããšå ¥åãããŸã§ãã¡ãã»ãŒãžãç¶ç¶çã«éä¿¡ãããšã³ãŒãåä¿¡ããŸãã
- ãšã©ãŒåŠç: ãµãŒããŒãå®è¡ãããŠããªãããŸãã¯æå®ãããããŒããæ£ãããªã/ãããã¯ãããŠããå Žåã«`ConnectionRefusedError`ãããçºçããŸãã
äŸãå®è¡ããŠã€ã³ã¿ã©ã¯ã·ã§ã³ã芳å¯ãã
ãã®äŸãå®è¡ããã«ã¯ïŒ
- ãµãŒããŒã³ãŒãã`server.py`ãšããŠãã¯ã©ã€ã¢ã³ãã³ãŒãã`client.py`ãšããŠä¿åããŸãã
- ã¿ãŒããã«ãŸãã¯ã³ãã³ãããã³ãããéãããµãŒããŒãå®è¡ããŸãïŒ`python server.py`ã
- å¥ã®ã¿ãŒããã«ãéããã¯ã©ã€ã¢ã³ããå®è¡ããŸãïŒ`python client.py`ã
- ã¯ã©ã€ã¢ã³ãã¿ãŒããã«ã«ã¡ãã»ãŒãžãå ¥åãããšã³ãŒããã¯ãããã®ã芳å¯ããŸãããµãŒããŒã¿ãŒããã«ã§ã¯ãæ¥ç¶ãšåä¿¡ããŒã¿ã瀺ãã¡ãã»ãŒãžã衚瀺ãããŸãã
ãã®ã·ã³ãã«ãªã¯ã©ã€ã¢ã³ãã»ãµãŒããŒéã®ã€ã³ã¿ã©ã¯ã·ã§ã³ã¯ãè€éãªåæ£ã·ã¹ãã ã®åºç€ã圢æããŸãããããã°ããŒãã«ã«ã¹ã±ãŒã«ããããšãæ³åããŠã¿ãŠãã ããããµãŒããŒã¯ç°ãªã倧éžã®ããŒã¿ã»ã³ã¿ãŒã§çšŒåãã倿§ãªå°ççå Žæããã®ã¯ã©ã€ã¢ã³ãæ¥ç¶ãåŠçããŸããããŒããã©ã³ã·ã³ã°ããããã¯ãŒã¯ã«ãŒãã£ã³ã°ãé 延管çã®ããã®é«åºŠãªæè¡ãå¿ èŠã«ãªããŸãããåºç€ãšãªããœã±ããã®ååã¯å€ãããŸããã
Pythonãœã±ããã«ããUDPéä¿¡ã®æ¢æ±
次ã«ãUDPãœã±ããã䜿çšããŠåæ§ã®ãšã³ãŒã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããšã§ãTCPãšUDPã察æ¯ããŠã¿ãŸããããUDPã¯ã³ãã¯ã·ã§ã³ã¬ã¹ã§ä¿¡é Œæ§ãäœãããšãèŠããŠãããŠãã ããããã®ãããå®è£ ããããã«ç°ãªããŸãã
UDPãµãŒããŒã®å®è£
UDPãµãŒããŒã¯éåžžã以äžã®æé ãå®è¡ããŸãã
- ãœã±ãããªããžã§ã¯ããäœæããŸãïŒ`SOCK_DGRAM`ã䜿çšïŒã
- ãœã±ãããã¢ãã¬ã¹ã«ãã€ã³ãããŸãã
- ããŒã¿ã°ã©ã ãç¶ç¶çã«åä¿¡ãã`recvfrom()`ã«ãã£ãŠæäŸãããéä¿¡å ã¢ãã¬ã¹ã«å¿çããŸãã
import socket
HOST = '0.0.0.0' # Listen on all interfaces
PORT = 65432 # Port to listen on
def run_udp_server():
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.bind((HOST, PORT))
print(f"UDP Server listening on {HOST}:{PORT}...")
while True:
data, addr = s.recvfrom(1024) # Receive data and sender's address
print(f"Received from {addr}: {data.decode()}")
s.sendto(data, addr) # Echo back to the sender
if __name__ == "__main__":
run_udp_server()
UDPãµãŒããŒã³ãŒãã®èª¬æïŒ
socket.socket(socket.AF_INET, socket.SOCK_DGRAM): ããã§ã®äž»ãªéãã¯ãUDPçšã®`SOCK_DGRAM`ã§ããs.recvfrom(1024): ãã®ã¡ãœããã¯ãããŒã¿ãšéä¿¡è ã®`(IP, port)`ã¢ãã¬ã¹ã®äž¡æ¹ãè¿ããŸããUDPã¯ã³ãã¯ã·ã§ã³ã¬ã¹ã§ãããããå¥ã®`accept()`åŒã³åºãã¯ãããŸãããã©ã®ã¯ã©ã€ã¢ã³ãããã€ã§ãããŒã¿ã°ã©ã ãéä¿¡ã§ããŸããs.sendto(data, addr): å¿çãéä¿¡ãããšãã¯ã`recvfrom()`ããååŸããå®å ã¢ãã¬ã¹ïŒ`addr`ïŒãæç€ºçã«æå®ããå¿ èŠããããŸãã- `listen()`ã`accept()`ãããã³åã ã®ã¯ã©ã€ã¢ã³ãæ¥ç¶ã®ããã®ã¹ã¬ããåŠçããªãããšã«æ³šç®ããŠãã ãããåäžã®UDPãœã±ããã¯ãæç€ºçãªæ¥ç¶ç®¡çãªãã«è€æ°ã®ã¯ã©ã€ã¢ã³ãããåä¿¡ããè€æ°ã®ã¯ã©ã€ã¢ã³ãã«éä¿¡ã§ããŸãã
UDPã¯ã©ã€ã¢ã³ãã®å®è£
UDPã¯ã©ã€ã¢ã³ãã¯éåžžã以äžã®æé ãå®è¡ããŸãã
- ãœã±ãããªããžã§ã¯ããäœæããŸãïŒ`SOCK_DGRAM`ã䜿çšïŒã
- `sendto()`ã䜿çšããŠãµãŒããŒã®ã¢ãã¬ã¹ã«ããŒã¿ãéä¿¡ããŸãã
- `recvfrom()`ã䜿çšããŠå¿çãåä¿¡ããŸãã
import socket
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 65432 # The port used by the server
def run_udp_client():
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
try:
message = input("Enter message to send (type 'quit' to exit): ")
while message.lower() != 'quit':
s.sendto(message.encode(), (HOST, PORT))
data, server = s.recvfrom(1024) # Data and server address
print(f"Received from {server}: {data.decode()}")
message = input("Enter message to send (type 'quit' to exit): ")
except Exception as e:
print(f"An error occurred: {e}")
finally:
s.close()
print("Socket closed.")
if __name__ == "__main__":
run_udp_client()
UDPã¯ã©ã€ã¢ã³ãã³ãŒãã®èª¬æïŒ
s.sendto(message.encode(), (HOST, PORT)): ã¯ã©ã€ã¢ã³ãã¯ãäºåã®`connect()`åŒã³åºããªãã«ããµãŒããŒã®ã¢ãã¬ã¹ã«çŽæ¥ããŒã¿ãéä¿¡ããŸããs.recvfrom(1024): éä¿¡è ïŒãµãŒããŒã§ããã¯ãïŒã®ã¢ãã¬ã¹ãšãšãã«ãå¿çãåä¿¡ããŸãã- UDPã®å Žåãããã«`connect()`ã¡ãœããåŒã³åºãããªãããšã«æ³šæããŠãã ãããUDPãœã±ããã§`connect()`ã䜿çšãããšãªã¢ãŒãã¢ãã¬ã¹ãåºå®ã§ããŸãããTCPã®æå³ã§ã®æ¥ç¶ã¯ç¢ºç«ãããŸãããããã¯åã«åä¿¡ãã±ããããã£ã«ã¿ãªã³ã°ãã`send()`ã®ããã©ã«ãã®å®å ãèšå®ããã ãã§ãã
äž»ãªéããšãŠãŒã¹ã±ãŒã¹
TCPãšUDPã®äž»ãªéãã¯ãä¿¡é Œæ§ãšãªãŒããŒãããã«ãããŸããUDPã¯é床ãšã·ã³ãã«ããæäŸããŸãããä¿èšŒã¯ãããŸãããã°ããŒãã«ãããã¯ãŒã¯ã§ã¯ãã€ã³ã¿ãŒãããã€ã³ãã©ã®å質ãè·é¢ã®é·ããæœåšçãªãã±ããæå€±çã®é«ãã«ãããUDPã®ä¿¡é Œæ§ã®äœããããé¡èã«ãªããŸãããããããªã¢ã«ã¿ã€ã ã²ãŒã ãã©ã€ããããªã¹ããªãŒãã³ã°ã®ããã«ãããããªé å»¶ã occasional ãªãã¬ãŒã èœã¡ãå€ãããŒã¿ã®åéä¿¡ããã蚱容ãããã¢ããªã±ãŒã·ã§ã³ã§ã¯ãUDPãåªããéžæè¢ãšãªããŸããã¢ããªã±ãŒã·ã§ã³èªäœãå¿ èŠã«å¿ããŠãç¹å®ã®ããŒãºã«æé©åãããã«ã¹ã¿ã ã®ä¿¡é Œæ§ã¡ã«ããºã ãå®è£ ã§ããŸãã
ã°ããŒãã«ãããã¯ãŒã¯ããã°ã©ãã³ã°ã®é«åºŠãªæŠå¿µãšãã¹ããã©ã¯ãã£ã¹
åºæ¬çãªã¯ã©ã€ã¢ã³ãã»ãµãŒããŒã¢ãã«ã¯åºç€çã§ãããç¹ã«å€æ§ãªã°ããŒãã«ãããã¯ãŒã¯ã§åäœããå®éã®ãããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ã¯ãããæŽç·Žãããã¢ãããŒããå¿ èŠãšããŸãã
è€æ°ã®ã¯ã©ã€ã¢ã³ãã®åŠçïŒäžŠè¡åŠçãšã¹ã±ãŒã©ããªãã£
ç§ãã¡ã®ã·ã³ãã«ãªTCPãµãŒããŒã¯ã䞊è¡åŠçã®ããã«ã¹ã¬ããã䜿çšããŸãããå°æ°ã®ã¯ã©ã€ã¢ã³ãã«å¯ŸããŠã¯ããŸãæ©èœããŸããããããäžçäžã®äœåãäœçŸäžãã®åæãŠãŒã¶ãŒã«ãµãŒãã¹ãæäŸããã¢ããªã±ãŒã·ã§ã³ã®å Žåãä»ã®ã¢ãã«ã®æ¹ãå¹ççã§ãã
- ã¹ã¬ããããŒã¹ã®ãµãŒããŒ: åã¯ã©ã€ã¢ã³ãæ¥ç¶ãç¬èªã®OSã¹ã¬ãããæã¡ãŸããå®è£ ã¯ç°¡åã§ãããã¹ã¬ããæ°ãå¢å ããã«ã€ããŠãããªãã®ã¡ã¢ãªãšCPUãªãœãŒã¹ãæ¶è²»ããå¯èœæ§ããããŸããPythonã®Global Interpreter Lock (GIL) ã¯ãCPUããŠã³ããªã¿ã¹ã¯ã®çã®äžŠåå®è¡ãå¶éããŸãããI/OããŠã³ããªãããã¯ãŒã¯æäœã§ã¯åé¡ã¯å°ãªãã§ãã
- ããã»ã¹ããŒã¹ã®ãµãŒããŒ: åã¯ã©ã€ã¢ã³ãæ¥ç¶ïŒãŸãã¯ã¯ãŒã«ãŒã®ããŒã«ïŒãç¬èªã®ããã»ã¹ãæã¡ãGILããã€ãã¹ããŸããã¯ã©ã€ã¢ã³ãã®ã¯ã©ãã·ã¥ã«å¯ŸããŠããå ç¢ã§ãããããã»ã¹äœæãšããã»ã¹ééä¿¡ã®ãªãŒããŒããããé«ããªããŸãã
- éåæI/O (`asyncio`): Pythonã®`asyncio`ã¢ãžã¥ãŒã«ã¯ãã·ã³ã°ã«ã¹ã¬ããã§ã€ãã³ãé§ååã®ã¢ãããŒããæäŸããŸããã³ã«ãŒãã³ã䜿çšããŠå€ãã®åæI/Oæäœãå¹ççã«ç®¡çããã¹ã¬ãããããã»ã¹ã®ãªãŒããŒããããªãã«åäœããŸããããã¯I/OããŠã³ããªãããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ã§éåžžã«ã¹ã±ãŒã©ãã«ã§ãããææ°ã®é«æ§èœãµãŒããŒãã¯ã©ãŠããµãŒãã¹ããªã¢ã«ã¿ã€ã APIã§ãã°ãã°æšå¥šãããæ¹æ³ã§ããç¹ã«ããããã¯ãŒã¯é å»¶ã«ããå€ãã®æ¥ç¶ãããŒã¿ã®å°çãåŸ ã€å¯èœæ§ãããã°ããŒãã«ãããã€ã¡ã³ãã§å¹æçã§ãã
- `selectors`ã¢ãžã¥ãŒã«: `epoll`ïŒLinuxïŒã`kqueue`ïŒmacOS/BSDïŒãªã©ã®OSåºæã®ã¡ã«ããºã ã䜿çšããŠãI/Oæäœã®å¹ççãªå€éåïŒè€æ°ã®ãœã±ãããèªã¿æžãå¯èœãã©ããããã§ãã¯ïŒãå¯èœã«ããäœã¬ãã«APIã§ãã`asyncio`ã¯`selectors`ã®äžã«æ§ç¯ãããŠããŸãã
ç°ãªãã¿ã€ã ãŸãŒã³ããããã¯ãŒã¯æ¡ä»¶ã§ãŠãŒã¶ãŒã«ä¿¡é Œæ§ãšå¹çæ§ããã£ãŠãµãŒãã¹ãæäŸããå¿ èŠãããã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠãé©åãªäžŠè¡åŠçã¢ãã«ãéžæããããšã¯æãéèŠã§ãã
ãšã©ãŒåŠçãšå ç¢æ§
ãããã¯ãŒã¯æäœã¯ãä¿¡é Œæ§ã®äœãæ¥ç¶ããµãŒããŒã®ã¯ã©ãã·ã¥ããã¡ã€ã¢ãŠã©ãŒã«ã®åé¡ãäºæãã¬åæãªã©ã«ãããæ¬è³ªçã«é害ãçºçããããã§ããå ç¢ãªãšã©ãŒåŠçã¯äžå¯æ¬ ã§ãã
- æ£åžžãªã·ã£ããããŠã³: ã¯ã©ã€ã¢ã³ããšãµãŒããŒã®äž¡æ¹ãæ¥ç¶ãã¯ãªãŒã³ã«éããã¡ã«ããºã ïŒ`socket.close()`ã`socket.shutdown(how)`ïŒãå®è£ ãããªãœãŒã¹ãè§£æŸããŠãã¢ã«éç¥ããŸãã
- ã¿ã€ã ã¢ãŠã: `socket.settimeout()`ã䜿çšããŠãããããã³ã°åŒã³åºããç¡æéã«ãã³ã°ã¢ããããã®ãé²ããŸããããã¯ãé å»¶ãäºæž¬äžèœãªã°ããŒãã«ãããã¯ãŒã¯ã«ãããŠéèŠã§ãã
- `try-except-finally`ãããã¯: ç¹å®ã®`socket.error`ãµãã¯ã©ã¹ïŒäŸïŒ`ConnectionRefusedError`ã`ConnectionResetError`ã`BrokenPipeError`ã`socket.timeout`ïŒããã£ããããé©åãªã¢ã¯ã·ã§ã³ïŒå詊è¡ããã°èšé²ãèŠåïŒãå®è¡ããŸãã`finally`ãããã¯ã¯ããœã±ãããªã©ã®ãªãœãŒã¹ãåžžã«éããããããšãä¿èšŒããŸãã
- ããã¯ãªãä»ãå詊è¡: äžæçãªãããã¯ãŒã¯ãšã©ãŒã®å Žåãææ°ããã¯ãªãïŒå詊è¡éã®åŸ ã¡æéãé·ãããïŒã䌎ãå詊è¡ã¡ã«ããºã ãå®è£ ããããšã§ãç¹ã«äžçäžã®ãªã¢ãŒããµãŒããŒãšããåãããå Žåã«ãã¢ããªã±ãŒã·ã§ã³ã®å埩åãåäžãããããšãã§ããŸãã
ãããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ã«ãããã»ãã¥ãªãã£ã®èæ ®äºé
ãããã¯ãŒã¯ãä»ããŠéä¿¡ãããããŒã¿ã¯ãã¹ãŠè匱ã§ããã»ãã¥ãªãã£ã¯æåªå äºé ã§ãã
- æå·åïŒSSL/TLSïŒ: æ©å¯ããŒã¿ã®å Žåã¯ãåžžã«æå·åã䜿çšããŠãã ãããPythonã®`ssl`ã¢ãžã¥ãŒã«ã¯ãæ¢åã®ãœã±ãããªããžã§ã¯ããã©ããããŠTLS/SSLïŒTransport Layer Security / Secure Sockets LayerïŒãä»ããå®å šãªéä¿¡ãæäŸã§ããŸããããã«ããããã¬ãŒã³ãªTCPæ¥ç¶ãæå·åããããã®ã«å€æããã転éäžã®ããŒã¿ãçèŽãæ¹ããããä¿è·ãããŸããããã¯å°ççãªå Žæã«é¢ä¿ãªããæ®éçã«éèŠã§ãã
- èªèšŒ: ã¯ã©ã€ã¢ã³ããšãµãŒããŒã®IDã確èªããŸããããã¯ãåçŽãªãã¹ã¯ãŒãããŒã¹ã®èªèšŒãããããå ç¢ãªããŒã¯ã³ããŒã¹ã®ã·ã¹ãã ïŒäŸïŒOAuthãJWTïŒãŸã§å€å²ã«ããããŸãã
- å ¥åæ€èšŒ: ã¯ã©ã€ã¢ã³ãããåä¿¡ããããŒã¿ã決ããŠä¿¡é Œããªãã§ãã ãããäžè¬çãªè匱æ§ïŒã€ã³ãžã§ã¯ã·ã§ã³æ»æãªã©ïŒãé²ãããã«ããã¹ãŠã®å ¥åããµãã¿ã€ãºããŠæ€èšŒããŸãã
- ãã¡ã€ã¢ãŠã©ãŒã«ãšãããã¯ãŒã¯ããªã·ãŒ: ãã¡ã€ã¢ãŠã©ãŒã«ïŒãã¹ãããŒã¹ãšãããã¯ãŒã¯ããŒã¹ã®äž¡æ¹ïŒãã¢ããªã±ãŒã·ã§ã³ã®ã¢ã¯ã»ã·ããªãã£ã«ã©ã®ããã«åœ±é¿ããããçè§£ããŠãã ãããã°ããŒãã«ãããã€ã¡ã³ãã®å Žåããããã¯ãŒã¯ã¢ãŒããã¯ãã¯ãç°ãªãå°åãã»ãã¥ãªãã£ãŸãŒã³éã®ãã©ãã£ãã¯ãããŒãå¶åŸ¡ããããã«ãã¡ã€ã¢ãŠã©ãŒã«ãèšå®ããŸãã
- ãµãŒãã¹æåŠïŒDoSïŒå¯Ÿç: ã¬ãŒãå¶éãæ¥ç¶å¶éããã®ä»ã®æªçœ®ãå®è£ ããŠãæªæã®ããããŸãã¯å¶çºçãªãªã¯ãšã¹ãã®æŽªæ°Žã«ãã£ãŠãµãŒããŒãéè² è·ã«ãªãã®ãé²ããŸãã
ãããã¯ãŒã¯ãã€ããªãŒããŒãšããŒã¿ã·ãªã¢ã«å
ç°ãªãã³ã³ãã¥ãŒã¿ã¢ãŒããã¯ãã£éã§æ§é åããŒã¿ã亀æããå Žåã2ã€ã®åé¡ãçºçããŸãã
- ãã€ããªãŒããŒïŒãšã³ãã£ã¢ã³ïŒ: ç°ãªãCPUã¯ããã«ããã€ãããŒã¿ïŒæŽæ°ãªã©ïŒãç°ãªããã€ããªãŒããŒïŒãªãã«ãšã³ãã£ã¢ã³ãšããã°ãšã³ãã£ã¢ã³ïŒã§æ ŒçŽããŸãããããã¯ãŒã¯ãããã³ã«ã¯éåžžãããããã¯ãŒã¯ãã€ããªãŒããŒãïŒããã°ãšã³ãã£ã¢ã³ïŒã䜿çšããŸããPythonã®`struct`ã¢ãžã¥ãŒã«ã¯ããã€ããªããŒã¿ãäžè²«ãããã€ããªãŒããŒã«ããã¯ããã³ã¢ã³ããã¯ããã®ã«éåžžã«è²Žéã§ãã
- ããŒã¿ã·ãªã¢ã«å: è€éãªããŒã¿æ§é ã®å ŽåãçããŒã¿ãéä¿¡ããã ãã§ã¯äžååã§ããããŒã¿æ§é ïŒãªã¹ããèŸæžãã«ã¹ã¿ã ãªããžã§ã¯ãïŒãéä¿¡çšã®ãã€ãã¹ããªãŒã ã«å€æããå床å
ã«æ»ãæ¹æ³ãå¿
èŠã§ããäžè¬çãªã·ãªã¢ã«å圢åŒã«ã¯ä»¥äžãå«ãŸããŸãã
- JSON (JavaScript Object Notation): 人éãèªè§£å¯èœã§ãåºããµããŒããããŠãããWeb APIãäžè¬çãªããŒã¿äº€æã«åªããŠããŸããPythonã®`json`ã¢ãžã¥ãŒã«ã䜿ãã°ç°¡åã§ãã
- Protocol Buffers (Protobuf) / Apache Avro / Apache Thrift: é«å¹çã§ãJSON/XMLãããããŒã¿è»¢éãå°ããé«éãªãã€ããªã·ãªã¢ã«å圢åŒã§ããç¹ã«ã倧éã®ãããã©ãŒãã³ã¹ãéèŠãªã·ã¹ãã ãã垯åå¹ ãæžå¿µãããå ŽåïŒäŸïŒIoTããã€ã¹ãæ¥ç¶ãå¶éãããå°åã®ã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ïŒã«åœ¹ç«ã¡ãŸãã
- XML: å¥ã®ããã¹ãããŒã¹ã®åœ¢åŒã§ãããæ°ããWebãµãŒãã¹ã§ã¯JSONã»ã©äººæ°ããããŸããã
ãããã¯ãŒã¯é å»¶ãšã°ããŒãã«ãªãŒããžã®å¯Ÿå¿
é å»¶ïŒããŒã¿è»¢éã®æç€ºåŸã転éãéå§ããããŸã§ã®é å»¶ïŒã¯ãã°ããŒãã«ãããã¯ãŒã¯ããã°ã©ãã³ã°ã«ããã倧ããªèª²é¡ã§ãã倧éžéã§æ°åããã¡ãŒãã«ãç§»åããããŒã¿ã¯ãæ¬è³ªçã«ããŒã«ã«éä¿¡ãããé«ãé å»¶ãçµéšããŸãã
- 圱é¿: é«ãé å»¶ã¯ã¢ããªã±ãŒã·ã§ã³ãé ããå¿çæ§ã®äœããã®ã«æãããããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã«åœ±é¿ãäžããŸãã
- è»œæžæŠç¥:
- ã³ã³ãã³ãããªããªãŒãããã¯ãŒã¯ïŒCDNïŒ: éçã³ã³ãã³ãïŒç»åãåç»ãã¹ã¯ãªããïŒããŠãŒã¶ãŒã«å°ççã«è¿ããšããžãµãŒããŒã«åæ£ãããŸãã
- å°ççã«åæ£ããããµãŒããŒ: ã¢ããªã±ãŒã·ã§ã³ãµãŒããŒãè€æ°ã®å°åïŒäŸïŒåç±³ããšãŒããããã¢ãžã¢å€ªå¹³æŽïŒã«ãããã€ããDNSã«ãŒãã£ã³ã°ïŒäŸïŒAnycastïŒãŸãã¯ããŒããã©ã³ãµãŒã䜿çšããŠããŠãŒã¶ãŒãæå¯ãã®ãµãŒããŒã«èªå°ããŸããããã«ãããããŒã¿ãç§»åããå¿ èŠãããç©ççè·é¢ãççž®ãããŸãã
- æé©åããããããã³ã«: å¹ççãªããŒã¿ã·ãªã¢ã«åã䜿çšããéä¿¡åã«ããŒã¿ãå§çž®ãããã€ããŒãªããŒã¿æå€±ã蚱容ããããªã¢ã«ã¿ã€ã ã³ã³ããŒãã³ãã§ã¯ãããäœãé å»¶ã®ããã«UDPãéžæããå¯èœæ§ããããŸãã
- ãªã¯ãšã¹ãã®ãããåŠç: å€ãã®å°ããªãªã¯ãšã¹ãã§ã¯ãªããããããå°æ°ã®å€§ããªãªã¯ãšã¹ãã«çµåããŠãé å»¶ãªãŒããŒããããååŽããŸãã
IPv6ïŒã€ã³ã¿ãŒãããã¢ãã¬ã¹ã®æªæ¥
åè¿°ã®ãšãããIPv4ã¢ãã¬ã¹ã®æ¯æžã«ãããIPv6ã¯ãŸããŸãéèŠã«ãªã£ãŠããŸããPythonã®`socket`ã¢ãžã¥ãŒã«ã¯IPv6ãå®å šã«ãµããŒãããŠããŸãããœã±ãããäœæãããšãã¯ãã¢ãã¬ã¹ãã¡ããªãŒãšããŠ`socket.AF_INET6`ã䜿çšããã ãã§ããããã«ãããã¢ããªã±ãŒã·ã§ã³ãé²åããã°ããŒãã«ã€ã³ã¿ãŒãããã€ã³ãã©ã¹ãã©ã¯ãã£ã«å¯Ÿå¿ã§ããããã«ãªããŸãã
# Example for IPv6 socket creation
import socket
s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
# Use IPv6 address for binding or connecting
# s.bind(('::1', 65432)) # Localhost IPv6
# s.connect(('2001:db8::1', 65432, 0, 0)) # Example global IPv6 address
IPv6ã念é ã«çœ®ããŠéçºããããšã§ãã¢ããªã±ãŒã·ã§ã³ã¯æãå¹ åºããªãŒãã£ãšã³ã¹ã«å°éã§ããããã«ãªããIPv6ã®ã¿ã®å°åãããã€ã¹ãå«ãŸããŸãã
Pythonãœã±ããããã°ã©ãã³ã°ã®å®äžçã¢ããªã±ãŒã·ã§ã³
Pythonãœã±ããããã°ã©ãã³ã°ãéããŠåŠãã æŠå¿µãšãã¯ããã¯ã¯ãåãªãåŠè¡çãªãã®ã§ã¯ãªããããŸããŸãªæ¥çã«ãããç¡æ°ã®å®äžçã¢ããªã±ãŒã·ã§ã³ã®æ§æèŠçŽ ã§ãã
- ãã£ããã¢ããªã±ãŒã·ã§ã³: åºæ¬çãªã€ã³ã¹ã¿ã³ãã¡ãã»ãŒãžã³ã°ã¯ã©ã€ã¢ã³ããšãµãŒããŒã¯TCPãœã±ããã䜿çšããŠæ§ç¯ã§ãããªã¢ã«ã¿ã€ã ã®åæ¹åéä¿¡ãå®èšŒããŸãã
- ãã¡ã€ã«è»¢éã·ã¹ãã : ãã¡ã€ã«ãå®å šãã€å¹ççã«è»¢éããããã®ã«ã¹ã¿ã ãããã³ã«ãå®è£ ããå€§èŠæš¡ãªãã¡ã€ã«ã忣ãã¡ã€ã«ã·ã¹ãã ã®ããã«ãã«ãã¹ã¬ãããå©çšããå¯èœæ§ããããŸãã
- åºæ¬çãªWebãµãŒããŒãšãããã·: ç°¡ç¥åãããããŒãžã§ã³ãæ§ç¯ããããšã§ãWebãã©ãŠã¶ãWebãµãŒããŒãšã©ã®ããã«éä¿¡ãããïŒHTTP over TCPã䜿çšïŒã®åºæ¬çãªã¡ã«ããºã ãçè§£ããŸãã
- ã¢ãã®ã€ã³ã¿ãŒãããïŒIoTïŒããã€ã¹éä¿¡: å€ãã®IoTããã€ã¹ã¯ãå€ãã®å Žåã«ã¹ã¿ã ã®è»œéãããã³ã«ã䜿çšããŠãTCPãŸãã¯UDPãœã±ãããä»ããŠçŽæ¥éä¿¡ããŸããPythonã¯IoTã²ãŒããŠã§ã€ããã³éçŽãã€ã³ãã§äººæ°ããããŸãã
- 忣ã³ã³ãã¥ãŒãã£ã³ã°ã·ã¹ãã : 忣ã·ã¹ãã ã®ã³ã³ããŒãã³ãïŒäŸïŒã¯ãŒã«ãŒããŒããã¡ãã»ãŒãžãã¥ãŒïŒã¯ãã¿ã¹ã¯ãšçµæã亀æããããã«ãœã±ããã䜿çšããŠéä¿¡ããããšããããããŸãã
- ãããã¯ãŒã¯ããŒã«: ããŒãã¹ãã£ããŒããããã¯ãŒã¯ç£èŠããŒã«ãã«ã¹ã¿ã 蚺æã¹ã¯ãªãããªã©ã®ãŠãŒãã£ãªãã£ã¯ããã°ãã°`socket`ã¢ãžã¥ãŒã«ã掻çšããŸãã
- ã²ãŒã ãµãŒããŒ: å€ãã®å Žåé«åºŠã«æé©åãããŠããŸãããå€ãã®ãªã³ã©ã€ã³ã²ãŒã ã®ã³ã¢éä¿¡å±€ã¯ãé«éã§äœé å»¶ã®æŽæ°ã®ããã«UDPã䜿çšãããã®äžã«ã«ã¹ã¿ã ã®ä¿¡é Œæ§ã¬ã€ã€ãŒãéããŠããŸãã
- APIã²ãŒããŠã§ã€ãšãã€ã¯ããµãŒãã¹éä¿¡: ããé«ã¬ãã«ã®ãã¬ãŒã ã¯ãŒã¯ããã䜿çšãããŸããããã€ã¯ããµãŒãã¹ããããã¯ãŒã¯ãä»ããŠéä¿¡ããæ¹æ³ã®æ ¹åºã«ããååã«ã¯ããœã±ãããšç¢ºç«ããããããã³ã«ãé¢äžããŠããŸãã
ãããã®ã¢ããªã±ãŒã·ã§ã³ã¯ãPythonã®`socket`ã¢ãžã¥ãŒã«ã®å€æ§æ§ã匷調ããŠãããéçºè ãããŒã«ã«ãããã¯ãŒã¯ãµãŒãã¹ããå€§èŠæš¡ãªã¯ã©ãŠãããŒã¹ã®ãã©ãããã©ãŒã ã«è³ããŸã§ãã°ããŒãã«ãªèª²é¡ã«å¯Ÿå¿ãããœãªã¥ãŒã·ã§ã³ãäœæããããšãå¯èœã«ããŸãã
çµè«
Pythonã®`socket`ã¢ãžã¥ãŒã«ã¯ããããã¯ãŒã¯ããã°ã©ãã³ã°ãæ·±ãæãäžããããã®åŒ·åã§ãããªãã芪ãã¿ãããã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããŸããIPã¢ãã¬ã¹ãããŒããããã³TCPãšUDPã®åºæ¬çãªéããšããã³ã¢æŠå¿µãçè§£ããããšã§ãå¹ åºããããã¯ãŒã¯å¯Ÿå¿ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸããç§ãã¡ã¯ãåºæ¬çãªã¯ã©ã€ã¢ã³ãã»ãµãŒããŒéã®ã€ã³ã¿ã©ã¯ã·ã§ã³ãå®è£ ããæ¹æ³ãæ¢æ±ãã䞊è¡åŠçãå ç¢ãªãšã©ãŒåŠçãäžå¯æ¬ ãªã»ãã¥ãªãã£å¯Ÿçãããã³ã°ããŒãã«æ¥ç¶ãšããã©ãŒãã³ã¹ã確ä¿ããããã®æŠç¥ã®éèŠãªåŽé¢ã«ã€ããŠè°è«ããŸããã
倿§ãªãããã¯ãŒã¯éã§å¹æçã«éä¿¡ããã¢ããªã±ãŒã·ã§ã³ãäœæããèœåã¯ã仿¥ã®ã°ããŒãã«åããããžã¿ã«ç°å¢ã«ãããŠäžå¯æ¬ ãªã¹ãã«ã§ããPythonã䜿çšãããšãå°ççãªå Žæã«é¢ä¿ãªãããŠãŒã¶ãŒãšã·ã¹ãã ãæ¥ç¶ãããœãªã¥ãŒã·ã§ã³ãéçºã§ããæ±çšæ§ã®é«ãããŒã«ãæã«å ¥ããããšãã§ããŸãããããã¯ãŒã¯ããã°ã©ãã³ã°ã®æ ãç¶ããã«ããããæ©èœçã§ããã ãã§ãªããçã«å埩åããããã°ããŒãã«ã«ã¢ã¯ã»ã¹å¯èœãªã¢ããªã±ãŒã·ã§ã³ãäœæããããã«ãä¿¡é Œæ§ãã»ãã¥ãªãã£ãã¹ã±ãŒã©ããªãã£ãåªå ããè°è«ããããã¹ããã©ã¯ãã£ã¹ãåãå ¥ããããšãå¿ããªãã§ãã ããã
Pythonãœã±ããã®åãæŽ»çšããã°ããŒãã«ãªããžã¿ã«ã³ã©ãã¬ãŒã·ã§ã³ãšã€ãããŒã·ã§ã³ã®æ°ããå¯èœæ§ãè§£ãæŸã¡ãŸãããïŒ
ããã«åœ¹ç«ã€ãªãœãŒã¹
- å ¬åŒPython `socket`ã¢ãžã¥ãŒã« ããã¥ã¡ã³ã: é«åºŠãªæ©èœãšãšããžã±ãŒã¹ã«ã€ããŠè©³ããåŠã³ãŸãã
- Python `asyncio` ããã¥ã¡ã³ã: éåžžã«ã¹ã±ãŒã©ãã«ãªãããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ã®ããã®éåæããã°ã©ãã³ã°ãæ¢æ±ããŸãã
- Mozilla Developer Network (MDN) ãããã¯ãŒã¯ã«é¢ããWebããã¥ã¡ã³ã: ãããã¯ãŒã¯æŠå¿µã«é¢ããåªããäžè¬ãªãœãŒã¹ã§ãã