ÇöÀç°Á : UNIX ¼ÒÄÏ ÀÀ¿ë ÇÁ·Î±×·¡¹Ö ÀÌÀü 4.1 ¼ÒÄÏÀÇ µ¿ÀÛ¸ðµå ´ÙÀ½: 4.3 äÆà Ŭ¶óÀ̾ðÆ® ÇÁ·Î±×·¥
4.2 äÆà ¼¹ö ÇÁ·Î±×·¥
¢º äÆà ¼¹ö(chat_server.c)´Â ÀÓÀÇÀÇ Å¬¶óÀ̾ðÆ®°¡ äÆÿ¡ Âü°¡ÇÏ´Â ¿äûÀ» Çϸé À̸¦ äÆà Âü°¡ ¸®½ºÆ®¿¡ Ãß°¡Çϸç, äÆÿ¡ Âü°¡ÇÏ°í Àִ Ŭ¶óÀ̾ðÆ®µéÀÌ º¸³»¿À´Â ¸Þ½ÃÁö¸¦ ¸ðµç äÆà Âü°¡ÀÚ¿¡°Ô ´Ù½Ã ¹æ¼ÛÇÏ´Â ±â´ÉÀ» ¼öÇàÇÑ´Ù.
4.2.1 äÆà ¼¹ö ±¸Á¶
¢º äÆà ¼¹ö´Â ÀÓÀÇÀÇ Å¬¶óÀ̾ðÆ®·ÎºÎÅÍÀÇ Ã¤Æà Âü°¡¿ä±¸¸¦ ó¸®ÇÏ¸é¼ µ¿½Ã¿¡ ¾î¶² Ŭ¶óÀ̾ðÆ®°¡ º¸³»¿Â äÆà ¸Þ½ÃÁö¸¦ ¸ðµç Ŭ¶óÀ̾ðÆ®¿¡°Ô ¹æ¼ÛÇÏ´Â ÀÏÀ» ó¸®ÇÏ¿©¾ß ÇÑ´Ù.
¢º ÀÌ¿Í°°ÀÌ ¼¹ö°¡ µÎ °¡Áö ÀÏÀ» º´ÇàÇÏ¿© ó¸®Çϱâ À§Çؼ »õ·Î¿î Ŭ¶óÀ̾ðÆ®°¡ Á¢¼ÓµÉ ¶§¸¶´Ù ÇÁ·Î¼¼½º¸¦ ¸¸µé´Â concurrent ¼¹ö·Î ±¸ÇöÇÏ´Â ¹æ¹ýÀÌ °¡´ÉÇÏ´Ù.
¢º ±×·¯³ª ó¸®ÇØ¾ß ÇÒ ÀÛ¾÷ÀÌ »ý±æ ¶§¸¶´Ù ÇÁ·Î¼¼½º¸¦ ¸¸µé¾î ³ª°¡´Â ¹æ½ÄÀº ÇÁ·Î±×·¥ ÀÛ¼ºÀº Æí¸®ÇÏÁö¸¸ ½Ã½ºÅÛ ÀÚ¿øÀÇ È°¿ë¸éÀ̳ª ÇÁ·Î±×·¥ÀÇ ¾ÈÁ¤ÀûÀÎ µ¿À۸鿡¼´Â ºÒ¸®ÇÑ °æ¿ì°¡ ¸¹´Ù.
¢º ¿©±â¼ ¼Ò°³Çϴ äÆà ¼¹ö ÇÁ·Î±×·¥ chat_server.c¿¡¼´Â apparent concurrent ¼¹ö ±¸Á¶¸¦ »ç¿ëÇÑ´Ù.
¢ºApparent concurrent ¼¹ö´Â concurrent ¼¹öó·³ ¿©·¯ Ŭ¶óÀ̾ðÆ®¿¡°Ô º´ÇàÇÏ¿© ¼ºñ½º¸¦ Á¦°øÇϸ鼵µ ÇÁ·Î¼¼½º¸¦ Ŭ¶óÀ̾ðÆ® ¼ö¸¸Å °è¼Ó º¹Á¦ÇÏÁö ¾Ê´Â ¹æ½ÄÀÌ´Ù.
¢º º» ¿¹Á¦¿¡¼´Â ÇϳªÀÇ ÇÁ·Î¼¼½º°¡ ¿©·¯ Ŭ¶óÀ̾ðÆ®¿ÍÀÇ Åë½ÅÀ» ´ã´çÇϵµ·Ï ÇÑ´Ù.
¢º ÇÑÆí äÆà ¼¹ö ÇÁ·Î±×·¥Àº Ŭ¶óÀ̾ðÆ®ÀÇ Á¢¼Ó¿äûÀ» ó¸®ÇÏ´Â µ¿½Ã¿¡ ´Ù¸¥ Ŭ¶óÀ̾ðÆ®µéÀÌ º¸³»¿Â ¸Þ½ÃÁö¸¦ ¸ðµç äÆà Âü°¡ÀÚ Å¬¶óÀ̾ðÆ®¿¡°Ô Àü´ÞÇØ¾ß ÇϹǷΠÇÁ·Î¼¼½º°¡ ¾î´À ÇÑ °÷¿¡ ¸ØÃß¾î ÀÖÀ» ¼ö ÀÖ´Â blocking ¸ðµå·Î µ¿ÀÛÇÏ¸é ¾È µÈ´Ù.
¢º µû¶ó¼ ¼ÒÄÏÀ» ÅëÇÑ I/O¸¦ ºñµ¿±â ¸ðµå·Î ó¸®ÇÏ¿©¾ß Çϴµ¥ À̸¦ À§ÇÏ¿© select() ½Ã½ºÅÛ ÄÝÀ» »ç¿ëÇÑ´Ù.
¢º ±×¸² 4-1¿¡ apparent concurrent ¼¹ö ¸ðµ¨À» ÀÌ¿ëÇÑ Ã¤Æà ¼¹öÀÇ µ¿ÀÛÀ» ³ªÅ¸³Â´Ù.
¢º ¼¹ö´Â ¸ÕÀú socket()À» È£ÃâÇÏ¿© äÆà Âü°¡ÀÚ¸¦ Á¢¼öÇÒ ¼ÒÄÏÀ» °³¼³ÇÏ°í(ÀÌ ¼ÒÄÏÀ» Ãʱâ¼ÒÄÏÀ̶ó°í ºÎ¸£°Ú´Ù) ÀÌ ¼ÒÄÏÀ» ÀÚ½ÅÀÇ ¼ÒÄÏÁÖ¼Ò¿Í bind()ÇØ µÐ´Ù.
¢º ´ÙÀ½¿¡ ÀÌ Ãʱâ¼ÒÄÏÀ» ´ë»óÀ¸·Î select()¸¦ È£ÃâÇÏ¿© Ãʱâ¼ÒÄÏ¿¡ ¾î¶² I/O º¯È°¡ »ý±æ ¶§±îÁö ±â´Ù¸°´Ù.
±×¸² 4-1 apparent concurrent ¸ðµ¨ÀÇ Ã¤Æà ¼¹ö
¢º Ãʱâ¼ÒÄÏ¿¡¼ óÀ½ ¹ß»ýÇÒ ¼ö ÀÖ´Â I/O º¯È´Â äÆà Âü°¡ÀÚ°¡ ¿¬°á¿äûÀ» º¸³»¿ÔÀ» ¶§Àε¥ À̶§ ¼¹ö´Â accept()¸¦ È£ÃâÇÏ¿© »õ·Î¿î Âü°¡ÀÚ Á¢¼ÓÀ» ó¸®ÇÏ°í accept()°¡ ¸®ÅÏÇÏ´Â ¼ÒÄϹøÈ£¸¦ Âü°¡ÀÚ ¸®½ºÆ®(client_s[])¿¡ µî·Ï½ÃŲ´Ù.
¢º ¼¹ö´Â ÀÌ »õ·Î »ý±ä ¼ÒÄÏ°ú Ãʱâ¼ÒÄÏÀ» ´ë»óÀ¸·Î ÇÏ¿© ´Ù½Ã select()¸¦ È£ÃâÇÑ´Ù.
¢º select() ÇÔ¼öÀÇ ±â´ÉÀº ¼ÒÄÏ¿¡¼ ¹ß»ýÇÏ´Â I/O º¯È¸¦ ±â´Ù¸®´Ù°¡ ÁöÁ¤µÈ I/O º¯È°¡ °¨½Ã ´ë»ó ¼ÒÄϵé Áß Çϳª¿¡¼¶óµµ ¹ß»ýÇϸé select() ¹®ÀÌ ¸®ÅϵȴÙ.
¢º ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼´Â select()°¡ ¸®ÅϵǾúÀ» ¶§ ¾î¶² ¼ÒÄÏ¿¡¼ ¾î¶² I/O º¯È°¡ ¹ß»ýÇÏ¿´´ÂÁö¸¦ È®ÀÎÇÏ¿© ÇÊ¿äÇÑ ÀÛ¾÷À» ó¸®ÇÏ¸é µÈ´Ù.
¢º ±×¸² 4-1¿¡ ¼¹ö°¡ Ãʱâ¼ÒÄÏ°ú Çϳª ÀÌ»óÀÇ Ã¤Æà Âü°¡ÀÚ ¸®½ºÆ®(client_s[])¸¦ ´ë»óÀ¸·Î ´Ù½Ã select()¸¦ È£ÃâÇÏ°í select() ¹®ÀÌ ¸®ÅϵǸé ÀÌ°ÍÀÌ Ãʱâ¼ÒÄÏ¿¡¼ ¹ß»ýÇÑ °ÍÀÎÁö(Áï, »õ·Î¿î äÆà Âü°¡ÀÚ°¡ ¿¬°á¿äûÀ» ÇÑ °ÍÀÎÁö) ¾Æ´Ï¸é ±âÁ¸ÀÇ Âü°¡ÀÚ Áß ´©±º°¡ äÆà ¸Þ½ÃÁö¸¦ º¸³½ °ÍÀÎÁö¸¦ ±¸ºÐÇÏ¿© ÇÊ¿äÇÑ ±â´ÉÀ» ¼öÇàÇÏ´Â °ÍÀ» ³ªÅ¸³Â´Ù.
¢º ±×¸² 4-2¿¡ äÆà ÇÁ·Î±×·¥ÀÇ ÀüüÀûÀÎ ±¸¼ºÀ» ³ªÅ¸³Â´Ù.
¢º ¼¹ö´Â Ãʱâ¼ÒÄÏ s¸¦ ÅëÇÏ¿© »õ·Î¿î äÆà Âü°¡ÀÚ¸¦ Á¢¼ö(accept)ÇÏ¸ç »õ·Î Âü°¡ÇÑ Å¬¶óÀ̾ðÆ®µéÀÇ ¼ÒÄϹøÈ£´Â ¹è¿ client_s[]¿¡ µé¾î ÀÖ°Ô µÈ´Ù.
¢º ¿¹¸¦µé¾î ±×¸² 4-2¿¡´Â ÇöÀç 4¸íÀÇ Ã¤Æà Âü°¡ÀÚ°¡ Àִµ¥ ¼¹ö ÇÁ·Î±×·¥Àº Ãʱâ¼ÒÄÏ s¸¦ Æ÷ÇÔÇÏ¿© ¸ðµÎ ´Ù¼¸ °³ÀÇ ¼ÒÄÏ¿¡¼ ¹ß»ýÇÏ´Â I/O º¯È¸¦ °¨ÁöÇϵµ·Ï select()¸¦ È£ÃâÇÏ¿©¾ß ÇÑ´Ù.
±×¸² 4-2 äÆà ¼¹ö¿Í Ŭ¶óÀ̾ðÆ®ÀÇ ¿¬°á°ü°è
(s: Ãʱâ¼ÒÄÏ, ,client_s[]: äÆà Âü°¡ÀÚÀÇ ¼ÒÄÏ ¹øÈ£ ¹è¿)
4.2.2 select() ½Ã½ºÅÛ ÄÝ
¢º select() ½Ã½ºÅÛ ÄÝÀÇ »ç¿ë ¹®¹ýÀº ´ÙÀ½°ú °°´Ù.
int select ( int maxfdp1, /* ÃÖ´ë ÆÄÀÏ(¹× ¼ÒÄÏ)¹øÈ£ Å©±â + 1 */ fd_set *readfds, /* Àбâ»óÅ º¯È¸¦ °¨ÁöÇÒ ¼ÒÄÏ ÁöÁ¤ */ fd_set *writefds, /* ¾²±â»óÅ º¯È¸¦ °¨ÁöÇÒ ¼ÒÄÏ ÁöÁ¤ */ fd_set *exceptfds, /* ¿¹¿Ü»óÅ º¯È¸¦ °¨ÁöÇÒ ¼ÒÄÏ ÁöÁ¤ */ struct timeval *tvptr); /* select() ½Ã½ºÅÛ ÄÝÀÌ ±â´Ù¸®´Â ½Ã°£ */ |
¢º select()ÀÇ Ã¹¹ø° ÀÎÀÚ maxfdp1Àº 'I/O º¯È¸¦ °¨½ÃÇÒ ÃÑ ¼ÒÄÏÀÇ °³¼ö +1'ÀÇ °ªÀ» ÁöÁ¤ÇÏ¿©¾ß Çϴµ¥ º¸Åë ÇöÀç openµÈ ¼ÒÄϹøÈ£ Áß °¡Àå Å« °ª¿¡ 1À» ´õÇÑ °ªÀ» »ç¿ëÇÑ´Ù.
¢º ÇÑÆí ½Ã½ºÅÛ³»¿¡¼ °³¼³ÇÒ ¼ö ÀÖ´Â ÆÄÀϱâ¼úÀÚÀÇ ÃÖ´ë°ªÀº <sys/types.h>¿¡ FD_SETSIZE·Î Á¤ÀǵǾî ÀÖ´Ù.
¢º fd_set(file descriptor set) ŸÀÔÀÇ ÀÎÀÚ readfds, writefds, exceptfds´Â °¢°¢ Àбâ, ¾²±â, ¿¹¿Ü»óȲ ¹ß»ý°ú °°Àº I/O º¯È°¡ ¹ß»ýÇÏ¿´À» ¶§ À̸¦ °¨ÁöÇÒ ´ë»óÀÌ µÇ´Â ¼ÒÄϵéÀ» ÁöÁ¤ÇÏ´Â ¹è¿Çü ±¸Á¶Ã¼ÀÌ´Ù.
¢º Áï, ÀÌ ¼¼ °¡Áö ±¸Á¶Ã¼¸¦ ÅëÇÏ¿© ¾î¶² ¼ÒÄÏ¿¡¼ ¾î¶² I/O º¯È ¹ß»ýÀ» °¨ÁöÇÒÁö¸¦ ¼±ÅÃÇÏ¿© ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù(µÚ¿¡¼ ÀÚ¼¼È÷ ¼³¸íÇÔ).
¢º ¸¶Áö¸· ÀÎÀÚ tvptrÀº select() ½Ã½ºÅÛ ÄÝÀÌ ±â´Ù¸®´Â ½Ã°£À» ÁöÁ¤Çϴµ¥ tvptrÀÌ NULLÀÎ °æ¿ì¿¡´Â ÁöÁ¤ÇÑ I/O º¯È°¡ ¹ß»ýÇÒ ¶§±îÁö °è¼Ó ±â´Ù¸®¸ç, 0ÀÎ °æ¿ì¿¡´Â ±â´Ù¸®Áö ¾Ê°í ¹Ù·Î ¸®ÅÏµÇ°í ±× ¿ÜÀÇ °ªÀÎ °æ¿ì¿¡´Â ÁöÁ¤µÈ ½Ã°£¸¸Å ¶Ç´Â µµÁß¿¡ I/O º¯È°¡ ¹ß»ýÇÒ ¶§±îÁö ±â´Ù¸°´Ù.
¢º fd_set ŸÀÔÀÇ ±¸Á¶Ã¼(À§¿¡¼ readfds, writefds, exceptfds)¿Í ¼ÒÄϹøÈ£¿ÍÀÇ °ü°è´Â ±×¸² 4-3°ú °°´Ù.
¢º ¿¹¸¦µé¾î ±×¸² 4-3¿¡¼ readfds ±¸Á¶Ã¼ÀÇ ¼ÒÄϹøÈ£ 0¹ø°ú 3¹øÀÌ 1·Î ¼¼Æ®µÇ¾î ÀÖÀ¸¹Ç·Î Å°º¸µå³ª(ÆÄÀϹøÈ£ 0¹ø), ¼ÒÄϹøÈ£ 3¿¡¼ ¾î¶² µ¥ÀÌÅÍ°¡ ÀԷµǾî ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ À̸¦ ÀÐÀ» ¼ö ÀÖ´Â »óÅ°¡ µÇ¸é select()¹®ÀÌ ¸®ÅϵȴÙ.
¢º ÇÑÆí writefds¿¡¼´Â ¼ÒÄϹøÈ£ 1¹ø°ú 3¹øÀÌ 1·Î ¼¼Æ®µÇ¾î ÀÖÀ¸¹Ç·Î ÆÄÀϱâ¼úÀÚ 1¹ø(Ç¥ÁØ Ãâ·Â)À̳ª ¼ÒÄϹøÈ£ 3¹øÀÌ write¸¦ ÇÒ ¼ö ÀÖ´Â »óÅ·Πº¯Çϸé(¿¹¸¦µé¸é ¼Û½Å ¹öÆÛ°¡ ºñ¿öÁü) select()¹®ÀÌ ¸®ÅϵȴÙ.
¢º ÀÌ¿Í°°ÀÌ °¢°¢ fd_set ŸÀÔ ±¸Á¶Ã¼¿¡ I/Oº¯È¸¦ °¨ÁöÇÒ ¼ÒÄÏ(¶Ç´Â ÆÄÀÏ)¹øÈ£¸¦ 1·Î ¼¼Æ®ÇÏ¿© select()¸¦ È£ÃâÇØ µÎ¸é ÇØ´ç Á¶°ÇÀÌ ¸¸Á·µÇ´Â ¼ø°£ select()¹®ÀÌ ¸®ÅϵȴÙ.
¢º ÇÑÆí UNIX¿¡¼´Â fd_set ŸÀÔÀÇ ±¸Á¶Ã¼¸¦ Æí¸®ÇÏ°Ô Ã³¸®ÇÒ ¼ö ÀÖµµ·Ï, ¿¹¸¦µé¸é ƯÁ¤ ¼ÒÄÏÀÇ I/O º¯È °¨Áö¸¦ ½±°Ô ¼±ÅÃÇϰųª Ãë¼ÒÇÒ ¼ö ÀÖµµ·Ï ¸ÅÅ©·Î¸¦ Á¦°øÇÏ°í ÀÖ´Ù(Ç¥ 4-1 ÂüÁ¶).
±×¸² 4-3 id_set ŸÀÔÀÇ ±¸Á¶Ã¼¿Í ¼ÒÄϹøÈ£¿ÍÀÇ °ü°è
FD_ZERO(fd_set *fdset) | *fdsetÀÇ ¸ðµç ºñÆ®¸¦ Áö¿î´Ù. |
FD_SET(int fd, fd_set *fdset) | *fdset Áß ¼ÒÄÏ fd¿¡ ÇØ´çÇÏ´Â ºñÆ®¸¦ 1·Î ÇÑ´Ù. |
FD_CLR(int fd, fd_set *fdset) | *fdset Áß ¼ÒÄÏ fd¿¡ ÇØ´çÇÏ´Â ºñÆ®¸¦ 0À¸·Î ÇÑ´Ù. |
FD_ISSET(int fd, fd_set *fdset) | *fdset Áß ¼ÒÄÏ fd¿¡ ÇØ´çÇÏ´Â ºñÆ®°¡ ¼¼Æ®µÇ¾î ÀÖÀ¸¸é ¾ç¼ö°ªÀÎ fd¸¦ ¸®ÅÏÇÑ´Ù. |
Ç¥ 4-1 fd_set¸¦ »ç¿ëÇϱâÀ§ÇÑ ¸ÅÅ©·Î
¢º select()¸¦ È£ÃâÇÏ·Á¸é ¸ÕÀú fd_set ±¸Á¶Ã¼¸¦ ¸¸µé¾î¾ß Çϴµ¥ º» Àý¿¡¼ ¼Ò°³ÇÒ chat_server.cÀÇ °æ¿ì¿¡´Â Àб⿡ ´ëÇÑ I/O º¯È¸¸ È®ÀÎÇÏ¸é µÇ¹Ç·Î fd_set ŸÀÔÀÇ ±¸Á¶Ã¼ read_fds Çϳª¸¸ ¼±¾ðÇÏ°í FD_ZERO(&read_fds)¸¦ È£ÃâÇÏ¿© read_fdsÀÇ ¸ðµç ¼ÒÄϹøÈ£ À§Ä¡¸¦ disable½ÃŲ´Ù.
¢º ´ÙÀ½¿¡´Â I/O º¯È¿¡ °ü½ÉÀ» °®´Â ¼ÒÄϹøÈ£(¶Ç´Â ÆÄÀϱâ¼úÀÚ)µéÀ» ¼±ÅÃÇÏ¿©¾ß Çϴµ¥, chat_server.c¿¡¼´Â Ŭ¶óÀ̾ðÆ®¿ÍÀÇ Á¢¼Ó ¿ä±¸¸¦ ó¸®ÇÒ Ãʱâ¼ÒÄÏ s¿Í °¢ äÆà Ŭ¶óÀ̾ðÆ®¸¶´Ù ¹èÁ¤µÈ ¼ÒÄϹøÈ£µéÀÇ ¹è¿ client_s[] µÎ °¡ÁöÀÇ ¼ÒÄÏÀÌ ÀÖ´Ù.
¢º ÇöÀç äÆÿ¡ Âü°¡ÇÏ°í Àִ Ŭ¶óÀ̾ðÆ® ¼ö¸¦ num_chatÀ̶ó°í ÇÏ¸é ¾Æ·¡¿Í °°ÀÌ FD_ZERO¸¦ »ç¿ëÇÏ¿© read_fds¸¦ ÃʱâÈÇÏ°í FD_SET¸¦ »ç¿ëÇÏ¿© I/O º¯È¸¦ °¨ÁöÇÒ ¼ÒÄϵéÀ» ¼±ÅÃÇÑ´Ù.
fd_set read_fds;
FD_ZERO(&read_fds); /* *read_fdsÀÇ ¸ðµç ¼ÒÄÏÀ» 0À¸·Î ÃʱâÈ */ FD_SET(s, &read_fds); /* Ãʱâ¼ÒÄÏ ¼±Åà */ for(i = 0; i < num_chat; i++) /* ¸ðµç Ŭ¶óÀ̾ðÆ® Á¢¼Ó ¼ÒÄÏ ¼±Åà */ FD_SET(client_s[i], &read_fds); |
¢ºÀ§¿¡¼ ÃʱâÈÇÑ read_fds¸¦ select()ÀÇ µÎ¹ø° ÀÎÀÚ(Áï, Àб⠺¯È °¨Áö¿ë fd_set)·Î ÁöÁ¤ÇÏ°í, ¾²±â ¹× ¿¹¿Ü ¹ß»ý¿¡ ÇØ´çÇÏ´Â fd_set´Â NULL·Î ÁöÁ¤ÇÏ¿© ´ÙÀ½°ú °°ÀÌ select()¸¦ È£ÃâÇÑ´Ù.
select(maxnfdsp1, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *)0); |
¢º ÇÑÆí select() ¹®ÀÇ Ã¹¹ø° ÀÎÀÚ 'I/O º¯È¸¦ °¨½ÃÇÒ ÃÑ ¼ÒÄÏÀÇ °³¼ö+1'ÀÇ °ªÀ¸·Î´Â ÇöÀç °³¼³µÈ 'ÃÖ´ë ¼ÒÄϹøÈ£ +1'À» »ç¿ëÇÏ¿´´Ù.
¢º À§ÀÇ select()´Â µÎ °¡Áö Á¾·ùÀÇ ÀԷ¿¡ ´ëÇÏ¿© ¸®ÅϵǹǷΠselect()°¡ ¸®ÅÏµÇ¸é ¾î¶² ÀÔ·ÂÀÌ ¹ß»ýÇÏ¿´´ÂÁö¸¦ ÆÇ´ÜÇÏ¿©¾ß Çϸç À̸¦ À§ÇÏ¿© FD_ISSET ¸ÅÅ©·Î¸¦ »ç¿ëÇÑ´Ù.
¢º FD_ISSETÀÇ »ç¿ë¹ýÀ» ¾Æ·¡¿¡ º¸¿´´Âµ¥ ¸ÅÅ©·Î FD_ISSET´Â read_fds ±¸Á¶Ã¼¿¡¼ ¼ÒÄϹøÈ£ s¿¡¼ I/O º¯È°¡ ÀÖ¾úÀ¸¸é ¾ç¼ö°ªÀÎ ¼ÒÄϹøÈ£ s¸¦ ¸®ÅÏÇÑ´Ù.
FD_ISSET(s, &read_fds); |
¡¡
¢º ¾Æ·¡¿¡¼ FD_ISSET ½ÇÇà °á°ú°¡ ¾ç¼öÀ̸é Ŭ¶óÀ̾ðÆ®·ÎºÎÅÍ ¿¬°á¿äû(Áï, äÆà Âü°¡¿äû)ÀÌ ¿Â °ÍÀ̹ǷΠaccept()¸¦ ºÒ·¯ äÆà Âü°¡¿äûÀ» ó¸®ÇÑ´Ù.
¢º ÇÑÆí client_s[] Áß ÇϳªÀÇ ¼ÒÄÏÀÌ ¼¼Æ®µÇ¾ú´Ù¸é ¾î¶² äÆà Âü°¡ÀÚ°¡ äÆà ¸Þ½ÃÁö¸¦ Àü¼ÛÇÑ °ÍÀ̹ǷΠÀÌ ¸Þ½ÃÁö¸¦ ¹Þ¾Æ ¸ðµç Âü°¡ÀÚ¿¡°Ô ¹æ¼ÛÇÏ¸é µÈ´Ù.
if (FD_ISSET(s,
&read_fds)) { /* Ãʱâ¼ÒÄÏ s¿¡¼ ÀÔ·Â ¹ß»ý */ clilen =sizeof(client_addr); client_fd = accept(s, (struct sockaddr *)&client_addr, &clilen); } /* Ŭ¶óÀ̾ðÆ® ¼ÒÄϹøÈ£ ¹è¿ client[]¸¦ Â÷·Ê·Î °Ë»ö */ for(i = 0; i < num_chat; i++) { if (FD_ISSET(client_s[i], &read_fds)) { /* ¼ÒÄÏ client_s[i]¿¡¼ äÆà ¸Þ½ÃÁö ¼ö½Å */ /* ¸ðµç Âü°¡ÀÚ¿¡°Ô äÆà ¸Þ½ÃÁö ¹æ¼Û */ } } |
¢º ÇÑÆí Ŭ¶óÀ̾ðÆ®°¡ äÆÿ¡¼ Å»ÅðÇÏ·Á¸é Á¾·á¹®ÀÚ(¿¹: exit)¸¦ º¸³»µµ·Ï ÇÏ¿´°í ¼¹ö´Â Á¾·á¹®ÀÚ¸¦ ¼ö½ÅÇÑ °æ¿ì À̸¦ È®ÀÎÇÏ°í(exitCheck() ÇÔ¼ö »ç¿ë) client_s[] ¹è¿¿¡¼ ÇØ´ç Ŭ¶óÀ̾ðÆ®ÀÇ ¼ÒÄϹøÈ£¸¦ »èÁ¦ÇÑ ÈÄ Ã¤Æà Âü°¡ÀÚ ¼ö num_chatÀ» 1 °¨¼Ò½ÃŲ´Ù.
¢º ¾Æ·¡´Â äÆà ¼¹ö¸¦ ¼öÇàÇÑ °á°ú¸¦ º¸ÀÌ°í ÀÖ´Ù.
# chat_server 4001
´ëÈ¹æ ¼¹ö ½ÇÇà.. |
4.2.3 ÇÁ·Î±×·¥ ÁÖ¿äºÎºÐ ¼³¸í
¢º chat_server.c¿¡¼ ¼ÒÄÏÀ» °³¼³ÇÒ ¶§ ÀÎÅÍ³Ý ÇÁ·ÎÅäÄÝ Ã¼°è(PF_INET)¸¦ »ç¿ëÇÏ¿´À¸¸ç ½ºÆ®¸² ÇüÅÂÀÇ(TCP) ÇÁ·ÎÅäÄÝÀ» ¼±ÅÃÇÏ¿´´Ù.
¢º ¾Æ·¡´Â ¼ÒÄÏÀ» ¸¸µé°í ¼ÒÄÏ¿¡ ÁÖ¼Ò¸¦ ºÎ¿©ÇÏ´Â(bind) °úÁ¤À» º¸¿´´Âµ¥ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ÀÇ ³»¿ëÀ» ³Î(NULL)·Î ÃʱâÈÇϱâ À§ÇÏ¿© ÇÔ¼ö bzero()¸¦ »ç¿ëÇÏ¿´´Ù.
¢º IP Áּҷδ ÇöÀç äÆà ¼¹ö ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÇ´Â È£½ºÆ®ÀÇ IP ÁÖ¼Ò¸¦(INADDR_ANY), ±×¸®°í ¼ºñ½º¸¦ Á¦°øÇÒ Æ÷Æ®¹øÈ£´Â ¼¹ö ÇÁ·Î±×·¥ ½ÇÇà½Ã »ç¿ëÀÚ°¡ ÀÔ·ÂÇÑ °ª(¿¹¸¦µé¸é 4001)À» »ç¿ëÇÏ¿´´Ù.
s = socket(PF_INET,
SOCK_STREAM, 0); bzero((char *)&server_addr, sizeof(server_addr)); server_addr.sin_family = PF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(atoi(argv[1])); |
¢º ¾Æ·¡´Â ¾î¶² Ŭ¶óÀ̾ðÆ®°¡ º¸³½ ¸Þ½ÃÁö¸¦ ´Ù¸¥ ¸ðµç Ŭ¶óÀ̾ðÆ®¿¡°Ô Àü¼ÛÇÏ´Â µ¿ÀÛÀ» ³ªÅ¸³Â´Ù.
¢º ¿©±â¼ ¹è¿ client_s[]¿¡´Â °¢ äÆà Âü°¡ÀÚµé°ú ¿¬°áµÇ´Â ¼ÒÄϹøÈ£µéÀÌ µé¾î ÀÖ´Ù.
¢º ù¹ø° for() ·çÇÁ´Â ÇöÀç äÆÿ¡ Âü°¡ÇÏ´Â ¸ðµç Ŭ¶óÀ̾ðÆ®¸¦ ´ë»óÀ¸·Î º¸³»¿Â äÆà ¸Þ½ÃÁö°¡ ÀÖ´ÂÁö °Ë»öÇϸç, µÎ¹ø° for() ·çÇÁ¿¡¼´Â äÆà ¸Þ½ÃÁö¸¦ ¸ðµç Ŭ¶óÀ̾ðÆ®¿¡°Ô ¹æ¼ÛÇÑ´Ù
/* äÆà ¸Þ½ÃÁö°¡
µµÂøÇß´ÂÁö °Ë»ç */ for(i = 0; i < num_chat; i++) { if(FD_ISSET(client_s[i], &read_fds)) { if((n = recv(client_s[i], rline, MAXLINE,0)) > 0) { rline[n] = '\0'; /* Á¾·á¹®ÀÚ ÀԷ½à äÆà ŻÅð ó¸® */ if(exitCheck(rline, escapechar, 5) == 1) { shutdown(client_s[i], 2); /* client_s[] Å©±â Á¶Àý */ if(i != num_chat - 1) client_s[i] = client_s[num_chat - 1]; num_chat--; continue; } /* ¸ðµç äÆà Âü°¡ÀÚ¿¡°Ô ¸Þ½ÃÁö ¹æ¼Û */ for(j = 0; j < num_chat; j++) send(client_s[j], rline, n, 0); printf("%s", rline); } } } |
¢º ÇÑÆí 3Àå¿¡¼ ¼Ò°³ÇÑ ÅäÅ© ÇÁ·Î±×·¥°ú ´Þ¸® äÆà ÇÁ·Î±×·¥¿¡¼´Â °¢ äÆà Âü°¡ÀÚ(Ŭ¶óÀ̾ðÆ®)µéÀÌ Å°º¸µå¿¡¼ ÀÔ·ÂÇÑ ¹®ÀÚ¿¸¸ ¼¹ö·Î Àü¼ÛÇÏ´Â °ÍÀÌ ¾Æ´Ï¶ó ÀÚ½Å(äÆà Âü°¡ÀÚ)ÀÇ À̸§À» ´ÙÀ½°ú °°ÀÌ ¸Þ½ÃÁö ¾Õ¿¡ ºÙ¿©¼ Àü¼ÛÇÑ´Ù.
[ö¼ö] hello everybody ? |
¡¡
¢º µû¶ó¼ Ŭ¶óÀ̾ðÆ®°¡ äÆÃÀ» Å»ÅðÇϱâ À§ÇÏ¿© exit¿Í °°Àº Á¾·á¹®ÀÚ¸¦ ÀÔ·ÂÇÏ¸é ¼¹ö´Â ÀÌ°ÍÀ» ã¾Æ³»±â À§ÇÏ¿© Ŭ¶óÀ̾ðÆ®°¡ Àü¼ÛÇÑ ¸Þ½ÃÁö Àüü¸¦ °Ë»öÇÏ¿© Á¾·á¹®ÀÚ¿ÀÌ µé¾î ÀÖ´ÂÁö¸¦ È®ÀÎÇÏ¿©¾ß ÇÑ´Ù.
¢º chat_server.c¿¡¼´Â ÀÌ°ÍÀ» ó¸®Çϱâ À§ÇÏ¿© »ç¿ëÀÚ Á¤ÀÇ ÇÔ¼ö exitCheck()¸¦ »ç¿ëÇÑ´Ù.
¢º chat_server.c ÇÁ·Î±×·¥ ¸®½ºÆ®
ÇöÀç°Á : UNIX ¼ÒÄÏ ÀÀ¿ë ÇÁ·Î±×·¡¹Ö ÀÌÀü 4.1 ¼ÒÄÏÀÇ µ¿ÀÛ¸ðµå ´ÙÀ½: 4.3 äÆà Ŭ¶óÀ̾ðÆ® ÇÁ·Î±×·¥