Win Socket Programming

 


1. À©¼ÓÀÇ ÀÌÇØ

    1-1. UNIX BSD Socket°ú WinsockÀÇ Â÷ÀÌ

     1-2. À©¼ÓÀÇ µ¿ÀÛ ¸ðµå

     1-3. À©¼ÓÀÇ ½ÃÀÛ°ú Á¾·á

2. À©¼ÓÀÇ µ¿ÀÛ

     2-1. ±âº»ÀûÀÎ À©¼Ó ÇÔ¼ö

     2-2. ºñµ¿±â ¸ðµåÀÇ »ç¿ë

     2-3. À©¼ÓÀÇ IPÁÖ¼Ò º¯È¯ ÇÔ¼ö

3. À©¼Ó ÇÁ·Î±×·¥ ¼­¹ö(Not Using MFC)

     3-1. ChatServer.cpp

     3-2. ChatClient.cpp

4. À©¼Ó äÆà ¼­¹ö(Use MFC in a Share DLL)

    4-1. ÇÁ·Î±×·¥ ÁÖ¿ä ºÎºÐ ¼³¸í

5. À©¼Ó äÆà Ŭ¶óÀ̾ðÆ®(Use MFC in a Share DLL)

    5-1. ÇÁ·Î±×·¥ ÁÖ¿ä ºÎºÐ ¼³¸í

6. À©¼ÓÀ» ÀÌ¿ëÇÑ Ã¤Æà ÇÁ·Î±×·¥(Use MFC in a Share DLL)

7. CASE ¿¬±¸


1. À©¼ÓÀÇ ÀÌÇØ

À©¼ÓÀº ¸¶ÀÌÅ©·Î¼ÒÇÁÆ®(Microsoft) À©µµ¿ì3.1 ¶Ç´Â À©µµ¿ì95¿¡¼­ Á¦°øÇÏ´Â TCP/IP ÇÁ·Î±×·¡¹ÖÀ» À§ÇÑ API(Application Program Interface)·Î¼­ »ç¿ë¹æ¹ý ¹× ±âº» µ¿ÀÛÀÌ UNIXÀÇ BSD ¼ÒÄÏ°ú °ÅÀÇ °°À¸¸ç BSD ¼ÒÄÏ°ú ¸¶Âù°¡Áö·Î Ŭ¶óÀ̾ðÆ®-¼­¹ö ¸ðµ¨À» ±âÃÊ·Î ÇÏ¿© ÀÌ¿ëµÈ´Ù.

       1-1. UNIX BSD Socket°ú WinsockÀÇ Â÷ÀÌ

À©¼ÓÀÇ »ç¿ë¹æ¹ý°ú ¹®¹ýÀÌ BSD ¼ÒÄÏÀÇ °æ¿ì¿Í À¯»çÇϱâ´Â ÇÏÁö¸¸ À©¼Ó°ú BSD ¼ÒÄÏ¿ëÀ¸·Î ÀÛ¼ºµÈ ÇÁ·Î±×·¥Àº ¼­·Î ȣȯ¼ºÀÌ ¾øÀ¸¸ç ÀÌ µÎ °¡Áö ¼ÒÄÏ ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ È£È¯¼ºÀ» °®À¸·Á¸é ¸¹Àº ºÎºÐÀ» ¼öÁ¤ÇÏ¿©¾ß ÇÑ´Ù. ¸ÕÀú À©µµ¿ì¿Í UNIX ¿î¿µÃ¼Á¦ÀÇ Â÷ÀÌÁ¡À» ºñ±³ÇÏ¸é ´ÙÀ½°ú °°´Ù.

  ù°, UNIX¿Í ´Þ¸® À©µµ¿ì 3.1 ÀÌÇÏ¿¡¼­´Â ¸ÖƼŽºÅ·À» Áö¿øÇÏÁö ¾Ê´Â´Ù.

À©µµ¿ì95´Â ¸ÖƼŽºÅ·°ú À¯»çÇÑ ¸ÖƼ¾²·¹µå(multi-thread)¸¦ Áö¿øÇϱâ´Â ÇÏÁö¸¸ À©¼ÓÀÌ Ã³À½ ¼Ò°³µÈ °ÍÀº ¸ÖƼŽºÅ·ÀÌ Áö¿øµÇÁö ¾Ê´Â À©µµ¿ì3.1¿¡¼­¿´À¸¸ç À©µµ¿ì95¿Í À©µµ¿ì3.1¿¡¼­ÀÇ ÇÁ·Î±×·¥ ȣȯ¼ºÀ» À¯ÁöÇϱâ À§ÇÏ¿© À©¼ÓÀº À©µµ¿ì95¿¡¼­µµ °è¼Ó '¸ÖƼŽºÅ·ÀÌ Áö¿øµÇÁö ¾Ê´Â' ȯ°æÀ» °¡Á¤ÇÏ°í ÀÖ´Ù. ÀÌ¿Í °°ÀÌ UNIX¿Í À©µµ¿ì ¿î¿µÃ¼Á¦ÀÇ ±âº»ÀûÀÎ Â÷ÀÌ·Î ÀÎÇÏ¿© À©¼ÓÀº BSD ¼ÒÄÏ°ú ³»ºÎÀûÀ¸·Î ¸Å¿ì ´Ù¸¥ Ư¼ºÀ» °®°í ÀÖÀ¸¸ç ÇÁ·Î±×·¥ ÀÛ¼º ½Ã¿¡µµ À̸¦ °í·ÁÇÏ¿©¾ß ÇÑ´Ù.

  µÑ°·Î À©¼ÓÀº ÁÖ·Î À©µµ¿ì ÇÁ·Î±×·¡¹ÖÀ¸·Î ±¸ÇöµÇ´Âµ¥, À©µµ¿ì ÇÁ·Î±×·¡¹ÖÀÌ '¸Þ½ÃÁö ±¸µ¿Çü ÇÁ·Î±×·¡¹Ö'À̶ó´Â °ÍÀÌ UNIX ÇÁ·Î±×·¥°ú Å©°Ô ´Ù¸¥ Á¡ÀÌ´Ù.

¸Þ½ÃÁö´Â '¾î¶² »ç°Ç(event)ÀÇ ¹ß»ýÀ» ¾Ë¸®´Â ½ÅÈ£'¶ó°í ÇÒ ¼ö Àִµ¥, ¸Þ½ÃÁö´Â »ç¿ëÀÚ°¡ ¸¸µç ÀÀ¿ë À©µµ¿ìµéÀÌ ¼­·Î ÁÖ°í¹Þ°Å³ª, À©µµ¿ì ¿î¿µÃ¼Á¦°¡ »ç¿ëÀÚ À©µµ¿ì¿¡°Ô Àü´ÞÇÏ´Â °ÍÀÌ´Ù. ÇÑÆí À©¼Ó ÇÁ·Î±×·¡¹Ö¿¡¼­´Â À©¼ÓÀÇ ±â´ÉÀ» Á¦°øÇÏ´Â ¶óÀ̺귯¸®·Î DLL(Dynamic Link Library)ÀÎ Winsock.dllÀ» »ç¿ëÇÑ´Ù. ÀÌ·¯ÇÑ DLL ¶óÀ̺귯¸®´Â ÄÄÆÄÀÏ ½Ã ¸µÅ© µÇ´Â °ÍÀÌ ¾Æ´Ï¶ó ÀÀ¿ë ÇÁ·Î±×·¥ ¼öÇà ½Ã ¸µÅ© µÈ´Ù. DLLÀ» »ç¿ëÇÏ´Â °ÍÀÇ ÀåÁ¡Àº ¿©·¯ ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ ÇϳªÀÇ DLLÀ» °øÀ¯ÇÏ¿© »ç¿ëÇÒ ¼ö ÀÖ´Ù´Â °ÍÀÌ´Ù.

¿¹¸¦ µé¸é ÇϳªÀÇ Winsock.dllÀÌ ¼öÇàÁßÀÌ¸é ¿©·¯ À©¼Ó ÀÀ¿ë ÇÁ·Î±×·¥µéÀÌ ÀÌ°ÍÀ» µ¿½Ã¿¡ »ç¿ëÇÒ ¼ö ÀÖ°Ô µÈ´Ù. ÀÌ¿Ü¿¡µµ BSD ¼ÒÄÏ°ú À©¼ÓÀº ¼ÒÄÏÀ» ¿­°í ´Ý´Â µ¥ ¾²ÀÌ´Â ÇÔ¼ö°¡ ´Ù¸¥µ¥ À©¼ÓÀÇ °æ¿ì WSAStartup(), WSACleanup()ÇÔ¼ö¸¦ ÅëÇØ ¼ÒÄÏ°ú Winsock.dll°úÀÇ °ü°è¸¦ ¼³Á¤, ÇØÁ¦ÇØ ÁÖ´Â °úÁ¤ÀÌ ÇÊ¿äÇÏ´Ù.

BSD ¼ÒÄÏó·³ close()¸¦ ÀÌ¿ëÇØ ¼ÒÄÏÀ» ´Ý´Â °ÍÀÌ ¾Æ´Ï¶ó closesocket() ÇÔ¼ö¸¦ »ç¿ëÇØ ´Ý¾Æ¾ß ÇÑ´Ù. ÀÌ¿Í °°Àº Â÷ÀÌ´Â UNIX¿Í À©µµ¿ì ¿î¿µÃ¼Á¦ÀÇ Æ¯¼ºÀÇ Â÷ÀÌ·Î ÀÎÇÑ °ÍÀ̸ç ÇÔ¼öÀÇ À̸§¸¸ ´Ù¸¥ °ÍÀÌ ¾Æ´Ï¶ó ÇÔ¼öÀÇ ±¸Ã¼ÀûÀÎ ³»ºÎ µ¿ÀÛµµ ¼­·Î ´Ù¸£´Ù.

 

      1-2. À©¼ÓÀÇ µ¿ÀÛ¸ðµå

BSD ¼ÒÄÏ°ú ¸¶Âù°¡Áö·Î À©¼ÓÀÌ Á¦°øÇÏ´Â ¼ÒÄϵµ ´ÙÀ½°ú °°Àº ¼¼ °¡Áö µ¿ÀÛ¸ðµå (operating mode)¸¦ °¡Áö°í ÀÖ´Ù.

Blocking ¸ðµå, Non-blocking ¸ðµå, Asynchronous(ºñµ¿±â) ¸ðµå °¢°¢¿¡ ´ëÇÏ ¾Ë¾Æº¸ÀÚ

 

           1-2-1. Blocking ¸ðµå

socket() ½Ã½ºÅÛ ÄÝÀ» È£ÃâÇÏ¿© ÇϳªÀÇ ¼ÒÄÏÀ» ¸¸µé¸é ÀÌ°ÍÀº µðÆúÆ®·Î blocking ¸ðµå·Î µ¿ÀÛÇÏ´Â ¼ÒÄÏÀÌ µÈ´Ù. ÀÌ·¯ÇÑ blocking ¸ðµåÀÇ ¼ÒÄÏÀ» ´ë»óÀ¸·Î accept(), closesocket(), connect(), recv(), recvfrom(), send(), sendto()¿Í °°Àº ÇÔ¼ö¸¦ È£ÃâÇϸé ÇÔ¼ö°¡ ¿øÇÏ´Â µ¿ÀÛÀ» ¿Ï·áÇÒ ¶§±îÁö ÇÔ¼ö¸¦ È£ÃâÇÑ ÇÁ·Î¼¼½º°¡ blockingµÉ ¼ö ÀÖ´Ù.

Áï, blocking ¸ðµåÀÇ ¼ÒÄÏ¿¡¼­´Â ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼­ À§¿Í °°Àº ÇÔ¼ö¸¦ È£ÃâÇÏ¿´À» ¶§ ±× µ¿ÀÛÀÌ ¿Ï·áµÇ¾î ÇÔ¼ö°¡ ¸®ÅÏ µÇ¾î¾ß ´ÙÀ½ ÀÛ¾÷À» ÇÒ ¼ö ÀÖ°Ô µÈ´Ù.

ÇÑÆí ¸ÖƼŽºÅ·ÀÌ Áö¿øµÇ´Â UNIX ÄÄÇ»ÅÍ¿¡¼­´Â blocking ¸ðµåÀÇ ¼ÒÄÏÀ» »ç¿ëÇÏ¿© ¾î¶² ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ ºí·Ï µÇ¾îµµ ÄÄÇ»ÅÍ Àüü µ¿ÀÛ¿¡´Â Å« ¹®Á¦°¡ µÇÁö ¾Ê´Â´Ù. ¿Ö³ÄÇÏ¸é ¸ÖƼŽºÅ· ¿î¿µÃ¼Á¦¿¡¼­´Â °¢°¢ÀÇ ÇÁ·Î¼¼½ºµéÀÌ µ¶¸³ÀûÀ¸·Î ¼öÇàµÇ¹Ç·Î ÇÑ ÇÁ·Î¼¼½º°¡ ºí·Ï µÇ¾î À־ ´Ù¸¥ ÇÁ·Î¼¼½ºµéÀº °è¼Ó ¼öÇàµÉ ¼ö Àֱ⠶§¹®ÀÌ´Ù.

±×·¯³ª À©µµ¿ì3.1°ú °°Àº ´ÜÀÏ Å½ºÅ· ¿î¿µÃ¼Á¦¿¡¼­´Â ÇÁ·Î±×·¥ÀÌ ÇÑ °÷¿¡ ºí·Ï µÇ¾î ÀÖÀ¸¸é PC Àüü°¡ ºí·Ï µÉ ¼ö ÀÖ´Ù. ¶ÇÇÑ blocking ¸ðµåÀÇ ¼ÒÄÏÀ» »ç¿ëÇϸé ÇϳªÀÇ ÇÁ·Î±×·¥¿¡¼­ ¿©·¯ °³ÀÇ ¼ÒÄÏÀ» µ¿½Ã¿¡ °³¼³ÇÏ¿© °¢°¢ÀÇ ÀÔÃâ·ÂÀ» ó¸®ÇÏ´Â ÇüÅÂÀÇ ÀÀ¿ë ÇÁ·Î±×·¥À» ÀÛ¼ºÇϱⰡ ¾î·Æ´Ù.

µû¶ó¼­ À©¼Ó ÇÁ·Î±×·¡¹Ö¿¡¼­´Â À̸¦ ÇØ°áÇϱâ À§ÇÏ¿© ¼ÒÄÏÀ» non-blocking ¸ðµå ¶Ç´Â ºñµ¿±â ¸ðµå·Î º¯°æÇÏ¿© »ç¿ëÇÏ´Â °ÍÀÌ ÇÊ¿äÇÏ´Ù.

 

          1-2-2. Non-blocking ¸ðµå

Non-blocking ¸ðµå ¼ÒÄÏÀ̶õ accept(), closesocket(), connect(), recv(), recvfrom(), send(), sendto()¿Í °°Àº ÇÔ¼ö°¡ È£ÃâµÇ¾úÀ» ¶§ ÇÔ¼öÀÇ ¿øÇÏ´Â µ¿ÀÛÀÌ ¿Ï·áµÇ´Â °Í°ú ¹«°üÇÏ°Ô ÀÏ´Ü ÇÔ¼ö°¡ Áï½Ã ¸®ÅÏ µÇ´Â ¼ÒÄÏÀ» ¸»ÇÑ´Ù.

¼ÒÄÏÀÌ Ã³À½ ¸¸µé¾îÁö¸é µðÆúÆ®·Î blocking ¸ðµå°¡ µÇ´Âµ¥ ÇÁ·Î±×·¡¸Ó´Â ÇÊ¿ä¿¡ µû¶ó blocking ¸ðµåÀÇ ¼ÒÄÏÀ» non-blocking ¸ðµå·Î ¹Ù²Ü ¼ö ÀÖ´Ù.

Non-blocking ¸ðµåÀÇ ¼ÒÄÏÀ» »ç¿ëÇÏ´Â ÀÌÀ¯´Â ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ ÀÌ°÷¿¡¼­ ¸ØÃß¾î ÀÖÁö(block) ¾Ê°Ô Çϱâ À§Çؼ­ÀÌ´Ù. Non-blcoking ¸ðµåÀÇ ¼ÒÄÏ¿¡¼­ ÇÔ¼ö È£ÃâÀÌ Áï½Ã ¸®ÅÏ µÇ¾úÀ» ¶§ ±× °á°ú´Â ´ÙÀ½°ú °°ÀÌ µÎ °¡Áö·Î Á¾·ù·Î ³ª´­ ¼ö ÀÖ´Ù.

1) ¼º°øÀûÀÎ ¸®ÅÏ: ÇÔ¼öÀÇ µ¿ÀÛÀÌ Áï½Ã ¼º°øÀûÀ¸·Î ¼öÇàµÇ¾úÀ½.

2) ¿¡·¯ ¸®ÅÏ : ÇÔ¼ö ¼öÇà Áß ¿¡·¯°¡ ¹ß»ýÇ߰ųª ÇÔ¼ö°¡ ºí·Ï µÇ¾úÀ½.

Áï, non-blocking ¸ðµå ¼ÒÄÏ¿¡¼­ Áï½Ã ¸®ÅÏ µÈ ÇÔ¼ö È£Ãâ °á°ú´Â ¼º°øÀûÀÎ °æ¿ìµµ ÀÖ°í ½ÇÆÐÇÑ °æ¿ìµµ ÀÖÀ» ¼ö ÀÖ´Ù. ¿¡·¯ ¸®ÅÏÀÎ °æ¿ì ¿¡·¯Äڵ尡 WSAEWOULDBLOCKÀ̸é, ÀÌ°ÍÀÇ Àǹ̴ ÇÔ¼öÀÇ µ¿ÀÛÀÌ À߸øµÇ¾ú´Ù´Â °ÍÀÌ ¾Æ´Ï¶ó ÀÌ ÇÔ¼ö°¡ µ¿ÀÛ ¿Ï·áµÉ ¶§±îÁö ±â´Ù¸°´Ù¸é blockµÉ ¼ö ÀÖ´Ù'´Â °ÍÀ» ÀǹÌÇÑ´Ù.

ÀÌ¿Í °°ÀÌ ¿¡·¯Äڵ尡 WSAEWOULDBLOCKÀÎ °æ¿ì ±× ¿øÀÎÀº ´ÙÀ½ÀÇ µÎ °¡Áö Áß Çϳª°¡ µÈ´Ù.

1) Winsock.dllÀÌ ÇÔ¼ö°¡ ¿øÇÏ´Â µ¿ÀÛÀ» ½ÃÀÛÇßÀ¸³ª ¾ÆÁ÷ Á¾·áµÇÁö ¾Ê¾ÒÀ½.

2) ÇÔ¼öÀÇ µ¿ÀÛÀÌ ½ÃÀÛµÇÁö ¸øÇßÀ¸¸ç ´Ù½Ã Àç ½Ãµµ¸¦ ÇÊ¿ä·Î ÇÔ.

À§ÀÇ Ã¹ ¹ø° °æ¿ì´Â ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ ÇÔ¼öÀÇ µ¿ÀÛ ¿Ï·á ½ÃÁ¡À» ¾Ë¾Æ¼­ ±× °á°ú¸¦ ó¸®ÇÏ¿©¾ß ÇÏ¸ç µÎ ¹ø° °æ¿ì´Â ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ ÀÌ ÇÔ¼ö°¡ ¼º°øÀûÀ¸·Î ½ÃÀÛµÉ ¶§±îÁö ÇÔ¼ö¸¦ °è¼Ó ¹Ýº¹ÇÏ¿© È£ÃâÇØ¾ß ÇÑ´Ù. ¾î¶² °æ¿ìÀ̵çnon-blocking ¸ðµå ¼ÒÄÏÀÇ Ã³¸®´Â ´Ù¼Ò º¹ÀâÇÏ¸ç µû¶ó¼­ ´ÙÀ½¿¡ ¼³¸íÇÒ ºñµ¿±â ¸ðµå¸¦ »ç¿ëÇÏ´Â °ÍÀÌ Æí¸®ÇÏ´Ù.

 

           1-2-3. Asynchronous(ºñµ¿±â) ¸ðµå

ºñµ¿±â ¸ðµå¿¡¼­µµ non-blocking ¸ðµå¿¡¼­Ã³·³ ¼ÒÄÏ °ü·Ã ÇÔ¼öÀÇ È£ÃâÀÌ ¹Ù·Î ¸®ÅÏ µÈ´Ù.

±×·¯³ª ºñµ¿±â ¸ðµå¿¡¼­´Â non-blocking ¸ðµå¿Í ´Þ¸®, ÇÔ¼öÀÇ µ¿ÀÛÀÌ ¿Ï·áµÇ´Â ½ÃÁ¡, ¶Ç´Â ÇÔ¼öÀÇ ½ÇÇàÀÌ ½ÃÀÛµÇÁö ¸øÇÑ °æ¿ì ´ÙÀ½¿¡ ´Ù½Ã Àç ½ÃµµÇÏ¿©¾ß ÇÏ´Â ½ÃÁ¡À» ½Ã½ºÅÛ(Winsock.dll)ÀÌ ¸Þ½ÃÁö ó¸® ¹æ½ÄÀ¸·Î ³ªÁß¿¡ ÀÀ¿ë ÇÁ·Î±×·¥¿¡°Ô ¾Ë·ÁÁØ´Ù. Áï, ºñµ¿±â ¸ðµåÀÇ ¼ÒÄÏ¿¡¼­ ¼ÒÄÏ°ü·Ã ÇÔ¼öÀÇ ½ÇÇà°á°úÀÇ ¿¡·¯Äڵ尡 WSAEWOULDBLOCKÀÏ ¶§ÀÇ Àǹ̴ ´ÙÀ½°ú °°´Ù.

1) ÇÔ¼öÀÇ µ¿ÀÛÀÌ ¿Ï·áµÇ¸é ±× ¶§ Winsock.dllÀÌ ¸Þ½ÃÁö¸¦ ÅëÇÏ¿© µ¿ÀÛÀÇ ¿Ï·á¸¦ ¾Ë·Á ÁÖ °Å³ª,

2) ÇÔ¼öÀÇ µ¿ÀÛÀÌ ½ÃÀÛÇÏÁö ¸øÇßÀ¸¸ç, ÇÔ¼ö¸¦ ´Ù½Ã È£ÃâÇØ¾ß ÇÒ ½ÃÁ¡À» ³ªÁß¿¡ ºñµ¿±â ÀûÀ¸·Î ¾Ë·ÁÁÖ°ÚÀ½.

UNIX¿Í °°Àº ¿î¿µÃ¼Á¦¿¡¼­´Â ÇÔ¼ö°¡ ºí·Ï µÇ´Â °ÍÀÌ ¹®Á¦°¡ µÇÁö ¾ÊÀ¸¹Ç·Î ¹Ýµå½Ã ºñµ¿±â ¸ðµåÀÇ ¼ÒÄÏÀ» »ç¿ëÇÒ ÇÊ¿ä´Â ¾ø´Ù. ±×·¯³ª À©¼Ó¿¡¼­´Â ºñµ¿±â ¸ðµå·Î ¼ÒÄÏÀ» »ç¿ëÇÏ´Â °ÍÀÌ Æí¸®ÇÏ´Ù.

 

           1-2-4. Blocking ÇÔ¼ö

ÇÑÆí blocking ¸ðµåÀÇ ¼ÒÄÏÀÌ ¾Æ´Ï´õ¶óµµ (Áï, non-blocking ¶Ç´Â ºñµ¿±â ¸ðµåÀÇ ¼ÒÄÏ¿¡¼­µµ) ¾î¶² ÇÔ¼öµéÀº ÇÔ¼ö ÀÚüÀÇ Æ¯¼º»ó ºí·Ï µÉ ¼ö ÀÖ´Â ÇÔ¼ö°¡ ÀÖ´Ù. ÀÌ·¯ÇÑ ÇÔ¼öµéÀº ³×Æ®¿÷ ½Ã½ºÅÛ(Áï, TCP/IP)ÀÌ ¾î¶² Á¤º¸¸¦ ¾ò¾î³»¾ß¸¸ ±× °á°ú¸¦ ¸®ÅÏ ÇÒ ¼ö ÀÖÀ¸¸ç ±× Á¤º¸¸¦ ¾ò´Âµ¥ ´Ù¼Ò ½Ã°£ÀÌ ÇÊ¿äÇϱ⠶§¹®ÀÌ´Ù.

¿¹¸¦ µé¾î È£½ºÆ®ÀÇ µµ¸ÞÀÎ ³×ÀÓÀ» ÀÔ·ÂÇÏ°í ÀÌ È£½ºÆ®ÀÇ IP ÁÖ¼Ò µîÀÇ Á¤º¸¸¦ ¾ò¾î³»´Â ÇÔ¼ö gethostbyname()ÀÌ Ã³¸®µÇ±â À§Çؼ­´Â, ³×Æ®¿÷ ½Ã½ºÅÛÀÌ DNS ¼­¹ö¿¡°Ô ÇÊ¿äÇÑ Á¤º¸¸¦ ¹®ÀÇÇÏ°í ±× °á°ú°¡ µµÂøÇÒ ¶§±îÁö ±â´Ù·Á¾ß¸¸ ÇÑ´Ù.

ÀÌ·¯ÇÑ ÇÔ¼öµéÀ» 'blocking ÇÔ¼ö'¶ó°í ºÎ¸£¸ç Ç¥ 5-1¿¡ ´ëÇ¥ÀûÀÎ blocking ÇÔ¼öµéÀ» Á¤¸®ÇÏ¿´´Ù.

ÇÔ¼ö

±â´É

select()

¼ÒÄÏÀÇ »óÅ º¯È­(Àбâ, ¾²±â, ¿À·ù ¹ß»ý)¸¦ ¾Ë·ÁÁÜ

gethostbyaddr()

È£½ºÆ® ÁּҷκÎÅÍ È£½ºÆ® Á¤º¸¸¦ ¾òÀ½

gethostbyname()

È£½ºÆ® À̸§À¸·ÎºÎÅÍ È£½ºÆ® Á¤º¸¸¦ ¾òÀ½

getprotobyname()

ÇÁ·ÎÅäÄÝ À̸§À¸·ÎºÎÅÍ ÇÁ·ÎÅäÄÝ ¹øÈ£¸¦ ¾òÀ½

getprotobynumber()

ÇÁ·ÎÅäÄÝ ¹øÈ£·ÎºÎÅÍ ÇÁ·ÎÅäÄÝ À̸§À» ¾òÀ½

getservbyname()

¼­ºñ½º À̸§À¸·ÎºÎÅÍ ¼­ºñ½º Á¤º¸¸¦ ¾òÀ½

getservbyport()

Æ÷Æ®¹øÈ£·ÎºÎÅÍ ¼­ºñ½º Á¤º¸¸¦ ¾òÀ½

Ç¥ 5-1 ´ëÇ¥ÀûÀÎ blocking ÇÔ¼ö

Ç¥ 5-1¿¡ ¼Ò°³ÇÑ blocking ÇÔ¼öµéÀº ¼ÒÄÏÀÇ µ¿ÀÛ ¸ðµå¿¡ °ü°è¾øÀÌ Ç×»ó ºí·Ï µÉ ¼ö ÀÖ´Â ÇÔ¼öÀÌ´Ù. ÀÌ·¯ÇÑ ÇÔ¼ö¸¦ »ç¿ëÇÒ ¶§ ÇÁ·Î±×·¥ÀÌ ºí·Ï µÇ´Â ¹®Á¦¸¦ ÇØ°áÇϱâ À§ÇÏ¿©, À©¼Ó¿¡¼­´Â À̵é blocking ÇÔ¼ö¿Í °°Àº ±â´ÉÀ» ¼öÇàÇϸ鼭 ½ÇÁ¦·Î´Â ºñµ¿±â ¸ðµå·Î µ¿ÀÛÇÏ´Â Áï, ÇÔ¼ö ½ÇÇà°á°ú¸¦ ºñµ¿±âÀûÀ¸·Î ¾Ë·ÁÁÖ´Â ºñµ¿±â ÇÔ¼öµéÀ» Á¦°øÇÏ°í ÀÖ´Ù.

 

ºñµ¿±â ÇÔ¼ö

±â ´É

WSAAsyncSelect()

¼ÒÄÏÀÇ I/O »óÅ º¯È­ Áï, ¿¬°á¿äû, µ¥ÀÌÅÍ ¼ö½Å, ¼Û½Å ¹öÆÛÀÇ »ç¿ë°¡´É µîÀÇ À̺¥Æ®¸¦ ½Ã½ºÅÛÀÌ ¸Þ½ÃÁö¸¦ ÅëÇÏ¿© ¾Ë·ÁÁÖµµ·Ï ¿äûÇÔ

WSAAsyncGetHostByAddr()

È£½ºÆ® ÁּҷκÎÅÍ È£½ºÆ® Á¤º¸¸¦ ¾òÀ½

WSAAsyncGetHostByName()

È£½ºÆ® À̸§À¸·ÎºÎÅÍ È£½ºÆ® Á¤º¸¸¦ ¾òÀ½

WSAAsyncGetProtoByName()

ÇÁ·ÎÅäÄÝ À̸§À¸·ÎºÎÅÍ ÇÁ·ÎÅäÄÝ ¹øÈ£¸¦ ¾òÀ½

WSAAsyncGetProtoByNumber()

ÇÁ·ÎÅäÄÝ ¹øÈ£·ÎºÎÅÍ ÇÁ·ÎÅäÄÝ À̸§À» ¾òÀ½

WSAAsyncGetServByName()

¼­ºñ½º À̸§À¸·ÎºÎÅÍ ¼­ºñ½º Á¤º¸¸¦ ¾òÀ½

WSAAsyncGetServByPort()

Æ÷Æ®¹øÈ£·ÎºÎÅÍ ¼­ºñ½º Á¤º¸¸¦ ¾òÀ½

Ç¥ 5-2 Blocking ÇÔ¼ö(Ç¥ 5-1)ÀÇ ±â´ÉÀ» ¼öÇàÇÏ´Â À©¼ÓÀÇ ºñµ¿±â ÇÔ¼ö

 

      1-3. À©¼ÓÀÇ ½ÃÀÛ°ú Á¾·á

           1-3-1. WSAStartup()

WSAStartup()Àº À©¼Ó °ü·Ã ÇÔ¼öµéÀ» »ç¿ëÇϱâ Àü¿¡ ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ ¹Ýµå½Ã È£ÃâÇØ¾ß ÇÏ´Â ÇÔ¼ö·Î, À©¼Ó ¶óÀ̺귯¸®ÀÎ Winsock.dllÀ» ÃʱâÈ­ÇÑ´Ù. WSAStartup()Àº ÀϹÝÀûÀ¸·Î À©µµ¿ì ¸Þ½ÃÁö WM_CREATE³ª WM_INITDIALOGÀÇ Ã³¸® ºÎºÐ¿¡¼­ È£ÃâµÈ´Ù.

WSAStartup()Àº µÎ °³ÀÇ ÀÎÀÚ¸¦ ÇÊ¿ä·Î Çϴµ¥, ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ ¿ä±¸ÇÏ´Â ÃÖ¼ÒÀÇ À©¼Ó ¹öÀü(1.0 ¶Ç´Â 1.1) °ª°ú, WSAStartup()ÀÌ ¼öÇàµÈ ÈÄ ³×Æ®¿÷ ½Ã½ºÅÛ(Winsock.dll)ÀÌ À©¼Ó °ü·Ã Á¤º¸¸¦ ¾Ë·ÁÁִµ¥ »ç¿ëÇÒ À©¼ÓÁ¤º¸ ±¸Á¶Ã¼, Áï WSADATA ŸÀÔÀÇ ±¸Á¶Ã¼ º¯¼öÀÇ ÁÖ¼Ò¸¦ ÇÊ¿ä·Î ÇÑ´Ù.

´ÙÀ½Àº ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ »ç¿ëÇÒ À©¼ÓÀÇ ¹öÀü °ªÀ» ÁöÁ¤ÇÏ°í WSAStartup()À» È£ÃâÇÏ´Â ¿¹ÀÌ´Ù.

WORD wVersionRequired ; /* »ç¿ëÇÒ À©¼Ó ¹öÀü °ª */

WSADATA wsaData ; /* À©¼ÓÁ¤º¸¸¦ ´ãÀ» ±¸Á¶Ã¼ */

wVersionRequired = MAKEWORD(0, 1); /* À©¼Ó ¹öÀü °ªÀ» 1.0À¸·Î ¼¼Æà */

WSAStartup(wVersionRequired, &wsaData); /* À©¼ÓÀÇ ½ÃÀÛ */

À§¿¡¼­ wsaData´Â WSADATA ŸÀÔÀÇ ±¸Á¶Ã¼ º¯¼ö·Î ¿©±â¿¡´Â WSAStartup() ÇÔ¼ö°¡ °³¼³ÇÏ¿© ¾ÕÀ¸·Î »ç¿ëÇÒ À©¼Ó¿¡ °üÇÑ Á¤º¸°¡ ¼ö·ÏµÇ¾î ¸®ÅÏ µÈ´Ù.

WSADATA ±¸Á¶Ã¼ÀÇ Á¤ÀÇ´Â ´ÙÀ½°ú °°´Ù(Winsock.h ÆÄÀÏ ÂüÁ¶).

typedef struct WSADATA {

WORD wVersion; /* À©¼Ó ¹öÀü (¿¹ 1.0) */

WORD wHighVersion; /* ÃÖ»óÀ§ÀÇ À©¼Ó ¹öÀü (¿¹ 1.1) */

char szDescription[WSADESCRIPTION_LEN+1]; /* ȸ»çÁ¤º¸ */

char szSystemStatus[WSASYS_STATUS_LEN+1]; /* ±¸¼ºÁ¤º¸ */

unsigned short iMaxSockets; /* ÇÑ ÇÁ·Î¼¼½º°¡ ¿­ ¼ö ÀÖ´Â ¼ÒÄÏ ¼ö */

unsigned short iMaxUdpDg; /* UDP ÆÐŶ Å©±â */

char FAR *lpVendorInfo; /* ȸ»çº° µ¥ÀÌÅÍ ±¸Á¶ÀÇ Æ÷ÀÎÅÍ */

} WSADATA;

 

          1-3-2. WSACleanup()

À©¼ÓÀÇ »ç¿ëÀ» Á¾·áÇÒ ¶§ È£ÃâÇϸç WSAStartup()¿¡ ´ëÀÀµÇ´Â ÇÔ¼öÀÌ´Ù.

 


2. À©¼ÓÀÇ µ¿ÀÛ

À©¼Ó °ü·Ã ÇÔ¼öµéÀÇ »ç¿ë¹ý Áï, ÇÔ¼öÈ£Ãâ ¼ø¼­¿Í ÇÔ¼öÀÇ ÀÎÀÚ ¹× °á°ú ¸®ÅÏ °ª µîÀº BSD ¼ÒÄÏÀÇ »ç¿ë¹ý°ú °ÅÀÇ °°´Ù.

 

 2-1. ±âº»ÀûÀÎ À©¼Ó ÇÔ¼ö

 

          2-1-1. socket()

À©¼Ó¿¡¼­µµ BSD ¼ÒÄÏ ÇÁ·Î±×·¥¿¡¼­¿Í °°ÀÌ socket() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© Åë½ÅÀÇ Ã¢±¸ ¿ªÇÒÀ» ÇÏ´Â ¼ÒÄÏÀ» »ý¼ºÇÑ´Ù. ¾Æ·¡´Â socket()ÀÇ »ç¿ë ¿¹·Î ÀÎÅÍ³Ý µµ¸ÞÀÎÀÇ ÁÖ¼Ò Ã¼°è¿¡¼­ ½ºÆ®¸²Çü ¼ÒÄÏÀ» °³¼³ÇÏ´Â °ÍÀ» º¸¿´´Ù.

 

SOCKET s; /* SOCKETÀº int ŸÀÔÀÌ´Ù */

char lpszMsg[100];

s = socket(AF_INET, SOCK_STREAM, 0);

if (s == INVALID_SOCKET) { /* ¼ÒÄÏ °³¼³ ¿¡·¯ ¹ß»ý */

wsprintf(lpszMsg, "socket() ¿¡·¯¹øÈ£ : %d", WSAGetLastError());

MessageBox(hwnd, lpszMsg, "¿¡·¯", MB_OK);

}


socket() ÇÔ¼öÀÇ Ã¹ ¹ø° ÀÎÀÚ´Â ¼ÒÄÏÀÌ »ç¿ëÇÒ ÁÖ¼Ò Ã¼°è(Address Family)ÀÇ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù. À©¼Ó ¹öÀü 1.1¿¡¼­´Â ÀÎÅÍ³Ý ÁÖ¼Òü°è(AF_INET)¸¸À» Áö¿øÇÑ´Ù.

µÎ ¹ø° ÀÎÀÚ´Â Æ®·£½ºÆ÷Æ® ÇÁ·ÎÅäÄÝÀ» ÁöÁ¤Çϴµ¥ ¿¬°áÇüÀÎ ½ºÆ®¸² ¼ÒÄÏÀ» °³¼³ÇÏ·Á¸é SOCK_STREAMÀ», ºñ¿¬°áÇüÀÎ µ¥ÀÌÅͱ׷¥ ÇüÅÂÀÇ ¼ÒÄÏÀ» °³¼³ÇÏ·Á¸é SOCK_ DGRAMÀ» ¼±ÅÃÇÑ´Ù.

¼¼ ¹ø° ÀÎÀÚ´Â ÇÁ·ÎÅäÄÝ Å¸ÀÔ(Type)Àε¥ ÀϹÝÀûÀ¸·Î 0À» ¾´´Ù.

 

socket()ÀÇ ¼öÇàÀÌ ¼º°øÇÑ °æ¿ì¿¡´Â »õ·Î¿î ¼ÒÄϹøÈ£¸¦ ¸®ÅÏÇÏ°í, ½ÇÆÐÇÑ °æ¿ì¿¡´Â INVALID_SOCKETÀÌ ¸®ÅÏ µÈ´Ù. À§¿¡¼­ WSAGetLastError()´Â °¡Àå ÃÖ±Ù¿¡ ¹ß»ýÇÑ À©¼Ó °ü·Ã ÇÔ¼öÀÇ ¿¡·¯Äڵ带 ¸®ÅÏ ÇÏ´Â ÇÔ¼öÀÌ´Ù.

MessageBox()´Â ¸Þ½ÃÁö »óÀÚ¸¦ ¸¸µé¾î È­¸é¿¡ Ãâ·ÂÇÏ´Â À©µµ¿ì ÇÔ¼öÀÌ´Ù. MessageBox()ÀÇ ¿øÇüÀº ´ÙÀ½°ú °°À¸¸ç À§¿¡¼­´Â ¿¡·¯ ¸Þ½ÃÁö¿Í OK ¹öÆ°À» Ãâ·ÂÇÏ°í ÀÖ´Ù.

 

int MessageBox (

HWND hWnd, /* À©µµ¿ì ÇÚµé */

LPCTSTR lpText, /* ÅؽºÆ® ¹è¿­ ÁÖ¼Ò */

LPCTSTR lpCaption, /* ĸ¼Ç ¹è¿­ ÁÖ¼Ò */

UINT uType); /* ¹Ú½º ½ºÅ¸ÀÏ */

À§¿¡¼­ HWND´Â À©µµ¿ì ÇÚµé ŸÀÔÀ» ³ªÅ¸³»´Âµ¥ ½ÇÁ¦·Î´Â int ŸÀÔÀÌ´Ù. LPCTSTRÀº long pointer const char string ŸÀÔÀ» ³ªÅ¸³»°í, UINT´Â unsigned int ŸÀÔÀ» ³ªÅ¸³½´Ù.

 

           2-1-2. bind()

bind()´Â ¼­¹ö¿¡¼­ È£ÃâµÇ´Âµ¥ socket()ÀÇ ¼öÇàÀ¸·Î »ý¼ºµÈ ¼ÒÄÏÀÇ ¹øÈ£(s)¿Í ¼­¹öÀÇ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼(SOCKADDR_IN)¸¦ ¿¬°áÇϱâ À§ÇØ È£ÃâÇÑ´Ù.

bind()ÀÇ Ã¹ ¹ø° ÀÎÀڷδ ¼ÒÄϹøÈ£¸¦, µÎ ¹ø° ÀÎÀÚ´Â ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ÀÇ ÁÖ¼Ò¸¦ ¾²°í ¼¼ ¹ø° ÀÎÀÚ´Â ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ÀÇ Å©±â¸¦ ¾´´Ù.

¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ SOCKADDRÀº BSD ¼ÒÄÏ¿¡¼­¿Í °°Àº ÇüŸ¦ °¡Áø´Ù. ¾Æ·¡´Â ÀÎÅÍ³Ý Àü¿ëÀ¸·Î Á¤ÀÇµÈ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ SOCKADDR_INÀ» º¸¿©ÁÖ°í ÀÖ´Ù.

struct SOCKADDR_IN {

short sin_family; /* ÁÖ¼Ò Ã¼°è */

u_short sin_port; /* Æ÷Æ®¹øÈ£ */

struct in_addr sin_addr; /* ÀÎÅÍ³Ý ÁÖ¼Ò (4¹ÙÀÌÆ®) */

char sin_zero[8]; /* ÃÑ 16¹ÙÀÌÆ®¸¦ ¸ÂÃß±â À§ÇÑ ¿©¹é */

}

struct in_addr {

u_long s_addr; /* 32ºñÆ®ÀÇ IP ÁÖ¼Ò¸¦ ÀúÀåÇÒ ±¸Á¶Ã¼ */

};

 

¾Æ·¡ ÇÁ·Î±×·¥ ÄÚµå´Â bind() ÇÔ¼öÀÇ »ç¿ë ¿¹Àε¥ Æ÷Æ®¹øÈ£·Î 3000¹øÀ» ÁöÁ¤ÇÏ°í ÀÖ´Ù.

#define PORT_NO 3000

SOCKET s;

char lpszMsg[100];

SOCKADDR_IN m_addr; /* ÀÎÅÍ³Ý Å¸ÀÔÀÇ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ */

/* ¼ÒÄÏ °³¼³ */

s = socket(AF_INET, SOCK_STREAM, 0);

/* ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ÀÇ °ªÀ» ÁöÁ¤ */

m_addr.sin_family = AF_INET;

m_addr.sin_addr.s_addr = htonl(INADDR_ANY);

m_addr.sin_port = htons(PORT_NO);

bind(s, (LPSOCKADDR)&m_addr, sizeof(m_addr));

 

À§¿¡¼­ SOCKADDR_IN°ú LPSOCKADDRÀº °¢°¢ ÀÎÅÍ³Ý Å¸ÀÔÀÇ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼¿Í ÀϹÝÀûÀÎ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼¸¦ ³ªÅ¸³Â´Ù. bind() ÇÔ¼ö´Â ¿ø·¡ LPSOCKADDR ŸÀÔÀÇ ÀÎÀÚ¸¦ »ç¿ëÇϵµ·Ï Á¤ÀǵǾî ÀÖÀ¸¹Ç·Î SOCKADDR_IN ŸÀÔÀÇ º¯¼öÀÎ m_addrÀ» bind()¸¦ È£ÃâÇϱâ Àü¿¡ LPSOCKADDR ŸÀÔÀ¸·Î castingÇÏ´Â °ÍÀÌ ÇÊ¿äÇÏ´Ù.

±×·¯³ª óÀ½ºÎÅÍ LPSOCKADDR ŸÀÔÀÇ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼¸¦ »ç¿ëÇÏÁö ¾ÊÀº ÀÌÀ¯´Â SOCKADDR_IN ŸÀÔÀÌ IP ÁÖ¼Ò¿Í Æ÷Æ®¹øÈ£ °ªÀ» ÁöÁ¤Çϱ⿡ Æí¸®Çϱ⠶§¹®ÀÌ´Ù.

 

           2-1-3. listen()

listen()Àº ¿¬°áÇü(TCP) ¼ÒÄÏÀ» °³¼³ÇÑ ¼­¹ö¿¡¼­ È£ÃâÇϴµ¥, ÁöÁ¤µÈ ¼ÒÄÏÀ» ÅëÇÏ¿© µé¾î¿À´Â Ŭ¶óÀ̾ðÆ®·ÎºÎÅÍÀÇ ¿¬°á¿äûÀ» ±â´Ù¸®´Â ÇÔ¼öÀÌ´Ù. listen()ÀÇ Ã¹ ¹ø° ÀÎÀÚ´Â ¼ÒÄϹøÈ£ÀÌ°í, µÎ ¹ø° ÀÎÀÚ¿¡´Â ¿¬°áÀ» ´ë±â½Ãų ¼ö Àִ Ŭ¶óÀ̾ðÆ®ÀÇ ÃÖ´ë ¼ö¸¦ ÁöÁ¤ÇÑ´Ù. listen()ÀÌ ¼º°øÀûÀ¸·Î ¼öÇàµÈ °æ¿ì¿¡´Â 0À» ¸®ÅÏÇϸç, ½ÇÆÐÇÑ °æ¿ì¿¡´Â SOCKET_ERROR¸¦ ¸®ÅÏ ÇÑ´Ù.

 

           2-1-4. accept()

accept()´Â ¿¬°áÇü ¼­¹ö¿¡¼­ listen()À» ½ÇÇàÇÏ¿© ¼öµ¿ ´ë±â¸ðµå·Î ¿¬°á¿äûÀ» ±â´Ù¸®´Ù°¡ Ŭ¶óÀ̾ðÆ®¿¡¼­ ¼­¹ö·Î ¿¬°á¿äûÀ» º¸³»¿À¸é À̸¦ ¼ö¶ôÇϱâ À§ÇÏ¿©, ¼­¹ö°¡ È£ÃâÇØ µÎ´Â ÇÔ¼öÀÌ´Ù. accept()ÀÇ ¼öÇàÀÌ ¼º°øÇÑ °æ¿ì¿¡´Â ¼ÒÄÏÀÌ Çϳª »õ·Î ¸¸µé¾îÁö¸ç »õ·Î ¸¸µé¾îÁø ¼ÒÄϹøÈ£°¡ ¸®ÅÏ µÈ´Ù. ¶ÇÇÑ À̶§ Á¢¼ÓµÈ Ŭ¶óÀ̾ðÆ®ÀÇ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ÀÇ Æ÷ÀÎÅÍ¿Í ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ÀÇ ±æÀÌ´Â accept() ÇÔ¼ö ÀÎÀÚ¸¦ ÅëÇÏ¿© ¾Ë·ÁÁØ´Ù.

´ÙÀ½Àº accept()ÀÇ »ç¿ë ¿¹Àε¥ accpet()°¡ ¼º°øÀûÀ¸·Î ¸®ÅÏ µÇ¸é ¿¬°áµÈ Ŭ¶óÀ̾ðÆ®ÀÇ ¼ÒÄÏÁÖ¼Ò°¡ ±¸Á¶Ã¼ m_client Addr¿¡ ½Ç·ÁÀÖ°Ô µÈ´Ù.

 

SOCKET s; /* ¼­¹ö°¡ °³¼³ÇÑ ¼ÒÄϹøÈ£ */

SOCKET client_s; /* accept()°¡ ¸®ÅÏÇÒ »õ·Î¿î ¼ÒÄϹøÈ£ */

char lpszMsg[100]; /* ¸Þ½ÃÁö ¹Ú½º¿¡ Ãâ·ÂÇÒ ¸Þ½ÃÁö */

SOCKADDR_IN m_addr; /* ¼­¹öÀÇ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ */

SOCKADDR_IN m_clientAddr; /* Á¢¼ÓµÈ Ŭ¶óÀ̾ðÆ®ÀÇ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ */

client_s = accept(s, (LPSOCKADDR)&m_clientAddr, &m_nClientAddrLen);

if (client_s == INVALID_SOCKET) {

wsprintf(lpszMsg, "accept() ¿¡·¯ ¹øÈ£: %d", WSAGetLastError());

MessageBox(hwnd, lpszMsg, "¿¡·¯", MB_OK);

} else {

wsprintf(lpszMsg, "client IP: %s",inet_ntoa(m_clientAddr.sin_addr.s_addr));

MessageBox(hwnd, lpszMsg, "¿¡·¯", MB_OK);

}

 

           2-1-5. connect()

¿¬°áÇü ¼ÒÄÏÀ» °³¼³ÇÑ Å¬¶óÀ̾ðÆ®°¡ ¼­¹ö¿Í Åë½ÅÀ» ÇÏ·Á¸é ¸ÕÀú ¼­¹ö¿Í ¿¬°áµÇ¾î¾ß Çϴµ¥ À̸¦ À§ÇÏ¿© Ŭ¶óÀ̾ðÆ®°¡ È£ÃâÇÏ´Â ÇÔ¼ö°¡ connect()ÀÌ´Ù. ÀÌ·¯ÇÑ Å¬¶óÀ̾ðÆ®ÀÇ connect() È£Ãâ¿¡ ´ëÇØ, ¼­¹ö°¡ ¹Ì¸® È£ÃâÇØ µÐ accept()°¡ Á¤»óÀûÀ¸·Î ó¸®µÇ¾î ¿¬°áÀÌ ¿Ï·áµÇ¸é connect()´Â 0À» ¸®ÅÏ ÇÑ´Ù.

´ÙÀ½Àº connect()ÀÇ »ç¿ë ¿¹ÀÌ´Ù.

#define SERVER_PORT_NO 3001

#define SERVER_IP_ADDR "210.110.180.118"

SOCKET s;

SOCKADDR_IN m_addr; /* ¿¬°áÇÒ ¼­¹öÀÇ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ */

char lpszMsg[100];

/* Ŭ¶óÀ̾ðÆ®°¡ ¿¬°áÇÏ·Á°í ÇÏ´Â ¼­¹öÀÇ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼¸¦ ¸¸µç´Ù */

m_addr.sin_family = AF_INET;

m_addr.sin_port = htons(SERVER_PORT_NO);

m_addr.sin_addr.s_addr = inet_addr(SERVER_IP_ADDR);

connect(s, (LPSOCKADDR)&m_addr, sizeof(m_addr));

 

           2-1-6. closesocket()

¼ÒÄÏÀÇ »ç¿ëÀÌ ³¡³­ ÈÄ ¼ÒÄÏÀ» ´Ý±â À§ÇØ È£ÃâÇϸç BSDÀÇ close()¿Í °°Àº µ¿ÀÛÀ» ÇÑ´Ù. closesocket()À» È£ÃâÇÏ¸é ¾ÆÁ÷ 󸮵ÇÁö ¾ÊÀº µ¥ÀÌÅ͵é, Áï ¼Û½Å ¹öÆÛ¿¡ µé¾î ÀÖÀ¸³ª ¾ÆÁ÷ ¸ñÀûÁö·Î Àü¼ÛµÇÁö ¾ÊÀº ÆÐŶ ¶Ç´Â ¼ö½Å ¹öÆÛ¿¡ µµÂøÇØ ÀÖÀ¸³ª ¾ÆÁ÷ À©¼ÓÀÌ ÀоîµéÀÌÁö ¾ÊÀº ÆÐŶµéÀÌ ¸ðµÎ ó¸®µÈ ÈÄ¿¡ ½ÇÁ¦·Î ¼ÒÄÏÀÌ Á¾·áµÈ´Ù. ±×·¯³ª ÀÌµé ¹Ì Ã³¸® ÆÐŶµéÀ» ¹Ù·Î ¹ö¸®°Å³ª, Á¤ÇØÁø ½Ã°£±îÁö¸¸ 󸮵DZ⸦ ±â´Ù¸®·Á¸é setsockopt()À» È£ÃâÇÏ¿© ¼ÒÄÏÀÇ ¿É¼ÇÀ» ¹Ù²Ù¾î µÎ¾î¾ß ÇÑ´Ù.

 

          2-1-7. setsockopt()

°³¼³µÈ ¼ÒÄÏÀÇ µ¿ÀÛ¿¡ °üÇÑ °¢Á¾ ¿É¼ÇÀ» ÁöÁ¤ÇÏ´Â µ¥ »ç¿ëµÈ´Ù. setsockopt()ÀÇ »ç¿ë ¹®¹ýÀº ´ÙÀ½°ú °°´Ù. setsockopt()Àº ¼Û¼ö½Å ¹öÆÛÀÇ Å©±â ÁöÁ¤, OOB(Out of band) µ¥ÀÌÅÍ Ã³¸® ¹æ¹ý, ¹æ¼ÛÇü ¸Þ½ÃÁöÀÇ Àü¼Û Çã¿ë µî ¿©·¯ °¡Áö ¼ÒÄÏ ¿É¼Ç ÁöÁ¤¿¡ »ç¿ëµÉ ¼ö ÀÖ´Ù.

ÁÖ·Î »ç¿ëµÇ´Â optnameÀ¸·Î´Â, ¸ÕÀú ¼ÒÄÏ Á¾·á ½Ã ¾ÆÁ÷ ¼Û¼ö½ÅÀÌ ¿Ï·áµÇÁö ¾ÊÀº ÆÐŶµéÀÇ Ã³¸® ¹æ¾ÈÀ» ÁöÁ¤Çϰųª(SO_LINGER), ¼ÒÄÏÀÇ µð¹ö±× Á¤º¸¸¦ Ãâ·ÂÇϵµ·Ï ÁöÁ¤Çϰųª(SO_DEBUG), ÇØ´ç ¼ÒÄÏ¿¡¼­ ¹æ¼ÛÇü ¸Þ½ÃÁö¸¦ Àü¼ÛÇÏ´Â °ÍÀ» Çã¿ëÇÏ´Â °Í(SO_ BROADCAST) µîÀÌ´Ù.

SO_LINGER ¿É¼ÇÀº closesocket() È£Ã⠽à Àü¼Û ½Ã½ºÅÛ(TCP/IP) ³»ºÎ¿¡ ³²¾Æ ÀÖ´Â ¹Ì Àü¼Û ÆÐŶ ¶Ç´Â ¾ÆÁ÷ ¼ö½Å 󸮵ÇÁö ¾ÊÀº ÆÐŶµéÀÇ Ã³¸® ¹æ¾ÈÀ» ¹Ì¸® ÁöÁ¤ÇÏ´Â °ÍÀ¸·Î À̶§ optvalÀº ´ÙÀ½°ú °°Àº ±¸Á¶Ã¼ lingerÀÇ ÁÖ¼Ò¸¦ °¡¸®Å°µµ·Ï ÇÑ´Ù.

struct linger {

int l_onoff; /* LINGER ¸ðµåÀÇ ¼±ÅÃ/Ãë¼Ò */

int l_linger; /* LINGER ½Ã°£ */

};

 

¿¹¸¦ µé¾î ¹Ì ó¸®µÈ ÆÐŶµéÀ» ¹Ù·Î ¹ö¸®Áö ¾Ê°í ÁöÁ¤µÈ ½Ã°£ ³»¿¡ 󸮵DZ⸦ ±â´Ù¸®·Á¸é(Áï, LINGER¸¦ ¼±ÅÃÇÏ·Á¸é) l_onoff¸¦ 1·Î ¼¼Æ®ÇÏ°í l_linger¿¡ ó¸® À¯¿¹½Ã°£À» ÃÊ´ÜÀ§·Î ÁöÁ¤ÇØ ÁØ´Ù. LINGER¸¦ ¼±ÅÃÇÏÁö ¾ÊÀ¸·Á¸é Áï, ¹Ì ó¸®µÈ ÆÐŶµéÀ» closesocket() È£Ã⠽à Áï½Ã ¹ö¸®µµ·Ï ÇÏ·Á¸é l_onoff¸¦ 0À¸·Î ÇÏ°í SO_DONTLINGER ¿É¼ÇÀ» ¼±ÅÃÇÏ¿© setsockopt()À» È£ÃâÇÏ¸é µÈ´Ù. ÇÑÆí ¼ÒÄÏÀÌ Ã³À½ ¸¸µé¾îÁö¸é ÈÄÀÚÀÇ »óÅÂÀÎ DONT- LINGER »óÅ·ΠµÇ¾î ÀÖ´Ù.

 

      2-2. ºñµ¿±â ¸ðµåÀÇ »ç¿ë

À©µµ¿ì(ƯÈ÷ 3.1¹öÀü)´Â ¸ÖƼŽºÅ·ÀÌ Áö¿øµÇÁö ¾Ê´Â ¿î¿µÃ¼Á¦À̹ǷΠ¾î¶² ÇÔ¼ö È£ÃâÀÌ ºí·ÏµÇ¾î ÀÖÀ¸¸é ½Ã½ºÅÛ Àüü°¡ ¸ØÃß¾î ÀÖ°Ô µÈ´Ù. À©¼Ó¿¡¼­ °³¼³ÇÑ ¼ÒÄÏÀº ±âº»ÀûÀ¸·Î blocking ¸ðµå·Î µ¿ÀÛÇϴµ¥ ¿¹¸¦ µé¾î accept()¸¦ È£ÃâÇÏ¿´À» ¶§ Ŭ¶óÀ̾ðÆ®·ÎºÎÅÍ ¿ä±¸µÈ connect()°¡ ¾ø´Ù¸é ¼­¹ö´Â ºí·Ï µÈ´Ù. À̸¦ ÇØ°áÇϱâ À§ÇÏ¿© ¼ÒÄÏÀ» ºñµ¿±â ¸ðµå·Î ¹Ù²Ù´Â °ÍÀÌ ÇÊ¿äÇѵ¥ À̸¦ À§ÇÏ¿© WSAAsyncSelect()¸¦ »ç¿ëÇÑ´Ù.

WSAAsyncSelect()¸¦ È£ÃâÇÔÀ¸·Î½á ¼ÒÄÏÀº ÀÚµ¿À¸·Î ºñµ¿±â ¸ðµå·Î ¹Ù²î°í ºí·Ï µÉ ¼ö ÀÖ´Â ÇÔ¼öµé(accept(), send(), recv() µî)À» ºñµ¿±â ¸ðµå·Î ó¸®ÇÒ ¼ö ÀÖ°Ô µÈ´Ù.

¾Æ·¡´Â WSAAsyncSelect()ÀÇ »ç¿ë ¹®¹ýÀÌ´Ù.

int WSAAsyncSelect (

SOCKET s, /* »óź¯È­(À̺¥Æ®)¸¦ °¨ÁöÇÒ ¼ÒÄϹøÈ£ */

HWND hWnd, /* ¼ÒÄÏ s¿¡¼­ À̺¥Æ®°¡ ¹ß»ýÇßÀ» ¶§

¸Þ½ÃÁö¸¦ ¹ÞÀ» À©µµ¿ì ÇÚµé */

UINT wMsg, /* À̺¥Æ® ¹ß»ý ½Ã º¸³¾ ¸Þ½ÃÁö */

long lEvent); /* °ü½ÉÀ» °®´Â À̺¥Æ®¸¦ ±ÔÁ¤ÇÏ´Â bitmask */

 

WSAAsyncSelect()´Â È£Ãâ Áï½Ã ¸®ÅÏ µÇ¸ç ¿¡·¯¹ß»ý ½Ã¿¡´Â SOCKET_ERROR¸¦ ¸®ÅÏ ÇÑ´Ù. ¿¡·¯°¡ ¹ß»ýÇÏ´Â °æ¿ì´Â Winsock.dllÀÌ ÃʱâÈ­µÇÁö ¾Ê¾Ò°Å³ª, ³×Æ®¿÷ÀÌ µ¿ÀÛÇÏÁö ¾Ê°Å³ª, ´Ù¸¥ blocking ÇÔ¼ö°¡ ó¸®ÁßÀ̰ųª, ÇÔ¼öÀÇ ÀÎÀÚ¸¦ À߸ø ÀÔ·ÂÇÑ °æ¿ìÀÌ´Ù.

WSAAsyncSelect()°¡ ¿¡·¯ ¾øÀÌ ¸®ÅÏ µÇ¸é ´ÙÀ½°ú °°Àº Á¶°ÇÀÌ ¸¸Á·µÈ °ÍÀÌ´Ù.

1) ¼ÒÄÏÀÌ ºñµ¿±â ¸ðµå·Î µÇ¾ú´Ù.

2) ¿øÇÏ´Â À̺¥Æ®°¡ ¹ß»ýÇÏ¸é ±× »ç½ÇÀÌ ¸Þ½ÃÁö·Î Àü´ÞµÉ °ÍÀÌ´Ù.

3) ÀÌ ¼ÒÄÏ¿¡ accept()°¡ È£ÃâµÇ¾î »õ·Î¿î ¼ÒÄÏÀÌ ¸¸µé¾îÁö¸é »õ·Î¿î ¼ÒÄÏ¿¡ ´ëÇؼ­µµ WSAAsyncSelect() È£Ã⠽à ¿ä±¸ÇÑ À̺¥Æ®¸¦ ¶È°°ÀÌ Ã³¸®ÇØ ÁØ´Ù.

WSAAsyncSelect()¸¦ È£ÃâÇÏ¸é ¼ÒÄÏÀº ºñµ¿±â ¸ðµå·Î ¹Ù²î°í ¼ÒÄÏ¿¡¼­ ÁöÁ¤µÈ À̺¥Æ®°¡ ¹ß»ýÇÏ¸é ¸Þ½ÃÁö Àü´ÞÀ» ÅëÇÏ¿© ÀÌ »ç½ÇÀ» WSAAsyncSelect()¸¦ È£ÃâÇÑ ÀÀ¿ë ÇÁ·Î±×·¥¿¡°Ô ¾Ë¸®°Ô µÈ´Ù. ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼­´Â °¢ À̺¥Æ®¿¡ ÇØ´çÇÏ´Â ±â´ÉÀ» ¼öÇàÇÏ¸é µÈ´Ù.

À̺¥Æ®ÀÇ Á¾·ù¿¡´Â ¼ö½Å µ¥ÀÌÅÍÀÇ µµÂø, µ¥ÀÌÅ͸¦ ¼Û½ÅÇÒ Áغñ°¡ µÊ, ¿¬°á¿äûÀ» acceptÇÒ Áغñ°¡ µÊ µîÀÇ »ç°ÇµéÀÌ Àִµ¥, ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ °ü½ÉÀ» °®´Â À̺¥Æ® Áï, ¾Ë°í ½ÍÀº ¼ÒÄÏÀÇ »óź¯È­´Â WSAAsyncSelect()¸¦ È£ÃâÇÒ ¶§ Event ÀÎÀÚ¿¡ ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.

ÇØ´ç ¼ÒÄÏ¿¡¼­, Event ÀÎÀÚ¿¡ ÁöÁ¤µÈ À̺¥Æ® Áß Çϳª¶óµµ ¹ß»ýÇϸé À©¼ÓÀº ÀÀ¿ë ÇÁ·Î±×·¥¿¡°Ô ÀÌ »ç½ÇÀ» ¾Ë·ÁÁÖ°Ô µÈ´Ù.

À̺¥Æ®ÀÇ Á¾·ù´Â Ç¥ 5-3°ú °°´Ù.

 

À̺¥Æ®

ÀÇ ¹Ì

FD_READ

¼ö½ÅµÈ µ¥ÀÌÅÍ°¡ ÀÖÀ½

FD_WRITE

µ¥ÀÌÅÍ ¼Û½ÅÀÌ °¡´ÉÇÔ(¼Û½Å ¹öÆÛ°¡ ºñ¾úÀ½)

FD_OOB

Out of band µ¥ÀÌÅÍ°¡ ¼ö½ÅµÊ

FD_ACCEPT

connect ¿äûÀÌ ÀÖ¾î accept 󸮰¡ °¡´ÉÇÔ (¼­¹ö¿¡¼­)

FD_CONNECT

connect ¿äûÀÌ ¼º°øÀûÀ¸·Î ÀÌ·ç¾îÁü (Ŭ¶óÀ̾ðÆ®¿¡¼­)

FD_CLOSE

¼ÒÄÏ Á¾·á°¡ ÀÌ·ç¾îÁü

Ç¥ 5-3 WSAAsyncSelect()¿¡¼­ ´Ù·ç´Â À̺¥Æ® Á¾·ù

Ç¥ 5-3¿¡¼­ FD_READ À̺¥Æ®´Â ÇØ´ç ¼ÒÄÏ¿¡ µ¥ÀÌÅÍ°¡ ¼ö½ÅµÇ¾î ÀÖÀ¸¸ç ÇöÀç À̸¦ ÀÐÀ» ¼ö ÀÖ´Ù´Â °ÍÀ» ¾Ë¸®´Â ¸Þ½ÃÁöÀÌ´Ù. À̶§ ÀÀ¿ë ÇÁ·Î±×·¥Àº ¼ÒÄÏ Á¾·ù¿¡ µû¶ó(TCP¶Ç´Â UDP) recv() ¶Ç´Â recvfrom()À¸·Î µ¥ÀÌÅ͸¦ ÀÐÀ¸¸é µÈ´Ù.

FD_WRITE´Â ¿¬°áÇü ¼ÒÄÏÀÌ »ó´ë¹æ ¼ÒÄÏ°ú óÀ½ ¿¬°áµÉ ¶§, Áï ¼­¹ö¿¡¼­´Â accept()°¡ ¼º°øÇϰųª Ŭ¶óÀ̾ðÆ®¿¡¼­´Â connect()°¡ ¼º°øÇÑ ¶§¿¡ óÀ½ ¹ß»ýÇÑ´Ù. ÀÌ ¶§ ÀÀ¿ë ÇÁ·Î±×·¥Àº send()¸¦ È£ÃâÇÏ¿© µ¥ÀÌÅ͸¦ ¼Û½ÅÇÒ ¼ö ÀÖ´Ù. µ¥ÀÌÅÍ°¡ ¼Û½Å¹öÆÛ¸¦ ¶°³ª ¼Û½Å¹öÆÛ°¡ ºñ°Ô µÇ¾îµµ FD_ WRITE°¡ ¹ß»ýÇϴµ¥, ÀÌ°ÍÀº ÀÌÁ¦ »õ·Î¿î ¼Û½ÅÀÌ °¡´ÉÇÏ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù.

FD_ACCEPT´Â ¼­¹ö ¼ÒÄÏ¿¡¼­ ¹ß»ýÇϴµ¥, Ŭ¶óÀ̾ðÆ®°¡ connect()·Î ¿¬°á¿äûÀ» ÇØ¿ÔÀ¸¹Ç·Î ¼­¹ö°¡ accept()¸¦ ó¸®ÇÒ ¼ö ÀÖ´Ù´Â °ÍÀ» ¾Ë·ÁÁØ´Ù. Áï, ÇØ´ç ¼ÒÄÏÀ¸·Î accept()¸¦ È£ÃâÇÒ ¼ö ÀÖÀ½À» ¾Ë·ÁÁØ´Ù.

FD_CONNECT´Â Ŭ¶óÀ̾ðÆ®¿¡¼­ ¹ß»ýÇϴµ¥ connect() ½Ã½ºÅÛ ÄÝÀÌ ¼º°øÀûÀ¸·Î ÀÌ·ç¾îÁ³À» ¶§ ¹ß»ýÇÏ´Â À̺¥Æ®ÀÌ´Ù.

¼ö½ÅÃø¿¡ µµÂøÇÑ ¸ðµç ÆÐŶÀº ÀϹÝÀûÀ¸·Î µµÂøÇÑ ¼ø¼­´ë·Î ¹öÆÛ¿¡ ÀúÀåµÈ ÈÄ Â÷·Ê´ë·Î 󸮵ȴÙ.

OOB µ¥ÀÌÅÍ´Â ÀÌ·¯ÇÑ ¼ø¼­¸¦ ¹«½ÃÇÏ°í ¿ì¼±ÀûÀ¸·Î 󸮵Ǿî¾ß ÇÒ µ¥ÀÌÅ͸¦ ¸»Çϸç À̸¦ ó¸®Çϱâ À§ÇÏ¿© OOB µ¥ÀÌÅÍ°¡ µµÂøÇϸé FD_OOB À̺¥Æ®°¡ ¹ß»ýÇÑ´Ù. OOB µ¥ÀÌÅÍ´Â 'Ctrl-C'°°Àº Á¦¾î ¹®ÀÚ¸¦ Àü´ÞÇϴµ¥ »ç¿ëµÈ´Ù.

WSAAsyncSelect()´Â °¢ ¼ÒÄÏ¿¡ ´ëÇÏ¿© ÇÑ ¹ø¸¸ ºÎ¸£´Â °ÍÀÌ ¾ÈÀüÇÏ´Ù. ¸¸¾à WSAAsyncSelect()¸¦ Áߺ¹ÇÏ¿© È£ÃâÇϸé ÀÌÀü¿¡ È£ÃâµÈ WSAAsyncSelect()ÀÇ °¢Á¾ ¿É¼ÇÀº ¹«½ÃµÇ¹Ç·Î ÁÖÀÇÇÏ¿©¾ß ÇÑ´Ù.

ÀÌÀü¿¡ ÁöÁ¤ÇÑ WSAAsyncSelect() ¿É¼ÇÀ» Ãë¼ÒÇÏ¿© ¾î¶² À̺¥Æ® ¹ß»ý¿¡ ´ëÇÑ ¸Þ½ÃÁö¸¦ ¼ö½ÅÇÏ°í ½ÍÁö ¾ÊÀ¸¸é wMsg=0, lEvent=0·Î ÇÏ¿© WSAAsyncSelect()¸¦ ´Ù½Ã È£ÃâÇÏ¸é µÈ´Ù.

¾Æ·¡´Â ¼ÒÄÏ m_s·Î Ŭ¶óÀ̾ðÆ®ÀÇ Á¢¼Ó¿äû connect()°¡ Á¢¼öµÇ¾î FD_ACCEPT À̺¥Æ®°¡ ¹ß»ýÇÏ¸é »ç¿ëÀÚ ¸Þ½ÃÁö(WM_USER + 1)¸¦ º¸³»µµ·Ï ÇÏ´Â ¿¹ÀÌ´Ù.

WSAAsyncSelect(m_s, m_hWnd, WM_USER + 1, FD_ACCEPT);

 

À̺¥Æ®¸¦ ó¸®ÇÏ´Â ÇÁ·Î±×·¥¿¡¼­´Â À̺¥Æ®ÀÇ Á¾·ù¸¦ ¾Ë±â À§ÇÏ¿© º¯¼ö lParam¸¦ ÂüÁ¶ÇÏ¿©¾ß Çϴµ¥ lParamÀÇ ÇÏÀ§ 16ºñÆ®¿¡´Â ¹ß»ýÇÑ À̺¥Æ®ÀÇ Á¾·ù°¡ ½Ç·ÁÀÖ°í »óÀ§ 16ºñÆ®¿¡´Â ¿¡·¯Äڵ尡 ½Ç·ÁÀÖ´Ù. ÀÌ·¯ÇÑ À̺¥Æ® Á¾·ù¿Í ¿¡·¯Äڵ带 lParam¿¡¼­ Æí¸®ÇÏ°Ô Ã£¾Æ³»±â À§ÇÏ¿© ¸ÅÅ©·Î WSAGETSELECTEVENT()¿Í WSA- GETSELECTERROR()°¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ´Ù.

#define WSAGETSELECTEVENT(lParam) LOWORD(lParam)

#define WSAGETSELECTERROR(lParam) HIWORD(lParam)

 

¾Æ·¡ÀÇ ÄÚµå´Â ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼­ ¹ß»ýÇÑ À̺¥Æ®°¡ FD_ACCEPTÀÎÁö¸¦ Áï, Ŭ¶óÀ̾ðÆ®·ÎºÎÅÍ ¿¬°á¿äûÀÌ ¿Í¼­ À̺¥Æ®°¡ ¹ß»ýÇß´ÂÁö¸¦ È®ÀÎÇÏ°í accept()¸¦ È£ÃâÇÏ´Â ¿¹ÀÌ´Ù.

if (WSAGETSELECTEVENT(lParam) == FD_ACCEPT) {

m_clientS = accept(m_s, NULL, NULL);

}

 

¾î¶² ¼ÒÄÏ¿¡¼­ À̺¥Æ®°¡ Çϳª ¹ß»ýÇÏ¸é ¸Þ½ÃÁö Àü¼ÛÀº Çѹø¸¸ ÀϾ´Ù. ±×·¯³ª ÀÌ ¼ÒÄÏ¿¡ °°Àº Á¾·ùÀÇ À̺¥Æ®°¡ ´Ù½Ã ¹ß»ýÇÒ ¼ö Àִµ¥, ÀÌ¿Í °°ÀÌ °°Àº À̺¥Æ®°¡ ´Ù½Ã ¹ß»ýÇÒ ¶§¸¶´Ù »õ·Î¿î ¸Þ½ÃÁö°¡ ÀÀ¿ë ÇÁ·Î±×·¥À¸·Î Àü´ÞµÇµµ·Ï ÇÏ´Â °ÍÀÌ ÇÊ¿äÇÏ´Ù.

¿¹¸¦ µé¾î FD_READ À̺¥Æ®°¡ ¹ß»ýÇÑ ¼ÒÄÏ¿¡ ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ recv() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© µ¥ÀÌÅ͸¦ ÀоîµéÀÎ ÈÄ¿¡ »õ·Î¿î µ¥ÀÌÅÍ°¡ ¼ö½ÅµÇ¸é FD_READ À̺¥Æ®°¡ ´Ù½Ã ¹ß»ýÇÏ¿©¾ß À̸¦ ÀÐÀ» ¼ö ÀÖ´Ù. ÀÌ°ÍÀº recv() È£Ãâ½Ã ³»ºÎÀûÀ¸·Î ÀÚµ¿À¸·Î 󸮵ǵµ·Ï µÇ¾î ÀÖ´Ù(Áï, revc() È£ÃâÀÌ WASAsyncSelect()¸¦ ´Ù½Ã È£ÃâÇÑ È¿°ú¸¦ ÁØ´Ù).

Ç¥ 5-4¿¡ °°Àº Á¾·ùÀÇ ¸Þ½ÃÁö¸¦ ¹Ýº¹ÇÏ¿© ¹ß»ý½ÃÅ°µµ·Ï ÇÏ´Â ÇÔ¼öµé°ú ÇØ´ç À̺¥Æ®¸¦ Á¤¸®ÇÏ¿´´Ù.

¿¹¸¦ µé¾î FD_ACCEPT À̺¥Æ®°¡ ¹ß»ýÇÏ¿´À» ¶§ accept()¸¦ È£ÃâÇÏ¿© À̸¦ ó¸®ÇÏ¸é »õ·Î¿î FD_ACCEPT°¡ ¹ß»ýÇÒ ¶§ °°Àº Á¾·ùÀÇ ¸Þ½ÃÁö°¡ ´Ù½Ã ÀÀ¿ë ÇÁ·Î±×·¥¿¡°Ô Àü´ÞµÈ´Ù.

 

¸Þ½ÃÁö ¹Ýº¹ ¹ß»ý ÇÔ¼ö

°ü·Ã À̺¥Æ®

accept()

FD_ACCEPT

send(), sendto()

FD_WRITE

recv(), recevfrom()

FD_READ

recv()

FD_OOB

Ç¥ 5-4 ¸Þ½ÃÁö ¹Ýº¹ ¹ß»ý ÇÔ¼ö

 

     2-3. À©¼ÓÀÇ IP ÁÖ¼Ò º¯È¯ ÇÔ¼ö

 

           2-3-1. WSAAsyncGetHostByAddr()

IP ÁּҷκÎÅÍ ÇØ´ç È£½ºÆ®ÀÇ À̸§°ú ±âŸ Á¤º¸¸¦ ¾Ë¾Æ³»±â À§ÇÑ ºñµ¿±â ÇÔ¼öÀ̸ç BSD ¼ÒÄÏÀÇ gethostbyaddr()°ú ¸¶Âù°¡Áö·Î hostent ±¸Á¶Ã¼¸¦ ¸®ÅÏ ÇÑ´Ù. hostent ±¸Á¶Ã¼ÀÇ ³»¿ëÀº ¾Æ·¡¿Í °°´Ù.

struct hostent {

char FAR * h_name; /* È£½ºÆ® À̸§ */

char FAR * FAR * h_aliases; /* È£½ºÆ®ÀÇ º°¸í ¸ñ·Ï */

shor h_addrtype; /* È£½ºÆ® ÁÖ¼Ò Å¸ÀÔ */

short h_length; /* ÁÖ¼ÒÀÇ ±æÀÌ */

char FAR * FAR * h_addr_list; /* ÁÖ¼Ò ¸ñ·Ï */

#define h_addr h_addr_list[0] /* ´ëÇ¥ÀûÀÎ ÁÖ¼Ò¸¦ h_addr¿¡ ÀúÀå */

};

 

WSAAsyncGetHostByAddr()ÀÇ »ç¿ë ¹®¹ýÀº ´ÙÀ½°ú °°´Ù.

HANDLE WSAAsyncGetHostByAddr (

HWND Hwnd, /* À©µµ¿ì ÇÚµé */

unsigned int Msg, /* ÀÌ ÇÔ¼ö Á¾·á½Ã Àü¼ÛÇÒ ¸Þ½ÃÁö */

const char *addr, /* È£½ºÆ®ÀÇ IP ÁÖ¼Ò */

int len, /* addrÀÇ ±æÀÌ */

int type, /* ÁÖ¼Ò Å¸ÀÔÀ¸·Î ÀÎÅͳݿ¡¼­´Â AF_INET */

char *buf, /* hostent ±¸Á¶Ã¼ÀÇ Æ÷ÀÎÅÍ */

int buflen

); /* bufÀÇ ±æÀÌ */

 

¾Æ·¡´Â WSAAsyncGetHostByAddr()ÀÇ »ç¿ë ¿¹Àε¥ IP ÁÖ¼Ò°¡ 203.252.65.3ÀΠȣ½ºÆ®ÀÇ µµ¸ÞÀÎ ³×ÀÓÀ» ¸Þ½ÃÁö ¹Ú½º¿¡ Ãâ·ÂÇÑ´Ù. ¾Æ·¡¿¡¼­ PHOSTENT´Â hostent ±¸Á¶Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ Å¸ÀÔÀ» ÁöÁ¤Çϸç MAXGETHOSTSTRUCT´Â hostent ±¸Á¶Ã¼¸¦ ´ã±â¿¡ ÃæºÐÇÑ Å©±âÀÇ »ó¼ö·Î Winsock.h¿¡ Á¤ÀǵǾî ÀÖ´Ù.

u_long m_Addr ;

char m_lpszHostEntryBuf[MAXGETHOSTSTRUCT] ;

PHOSTENT m_phostent; /* hostent ±¸Á¶Ã¼ Æ÷ÀÎÅÍ */

m_Addr = inet_addr("203.252.65.3");

WSAAsyncGetHostByAddr(m_hWnd, WM_USER_ASYNCGETHOSTBYADDR,

(char *)&m_Addr, 4, PF_INET, m_lpszHostEntryBuf, MAXGETHOSTSTRUCT) ;

m_phostent = (PHOSTENT)m_lpszHostEntryBuf ;

MessageBox(hwnd, m_phostent->h_name, "È£½ºÆ® À̸§", MB_OK);

 

ÇÑÆí WSAAsyncGetXByY°ú °°Àº ÇüÅÂÀÇ ºñµ¿±â ÇÔ¼öÀÇ ½ÇÇà °á°ú´Â lParam¿¡ µé¾îÀÖ°Ô µÈ´Ù.

lParamÀÇ »óÀ§ 16ºñÆ®¿¡´Â ¿¡·¯Äڵ尡 ÇÏÀ§ 16ºñÆ®¿¡´Â ºñµ¿±â ÇÔ¼ö ½ÇÇà °á°ú°¡ µé¾îÀÖ´Â ¹öÆÛÀÇ Å©±â°¡ µé¾î ÀÖ´Ù. ÀÌ·¯ÇÑ ¿¡·¯ °ª°ú ¹öÆÛÀÇ Å©±â °ªÀ» lParamÀ¸·ÎºÎÅÍ Æí¸®ÇÏ°Ô ¾Ë¾Æ³»±â À§ÇÏ¿© WSAGETASYNCERROR()¿Í WSAGETASYNCBUFLEN() ¸ÅÅ©·Î°¡ °¢°¢ Á¤ÀǵǾî ÀÖ´Ù.

 

           2-3-2. WSAAsyncGetServByName()

ÀÌ ÇÔ¼ö´Â ftp, mail°ú °°Àº TCP/IP Ç¥ÁØ ÀÀ¿ë ÇÁ·Î±×·¥ÀÇ Æ÷Æ®¹øÈ£¸¦ ã±â À§ÇØ »ç¿ëµÇ´Â ºñµ¿±â ÇÔ¼öÀÌ´Ù. ÀÌ ÇÔ¼ö°¡ ¼º°øÀûÀ¸·Î ¼öÇàµÇ¸é servent¶ó´Â ±¸Á¶Ã¼ÀÇ Æ÷ÀÎÅ͸¦ ¸®ÅÏÇϴµ¥ servent ±¸Á¶Ã¼ÀÇ ³»¿ëÀº ´ÙÀ½°ú °°´Ù.

struct servent {

char FAR * s_name; /* °ø½ÄÀûÀÎ ¼­ºñ½º À̸§ */

char FAR * FAR * s_aliases; /* ¼­ºñ½ºÀÇ º°¸í ¸®½ºÆ® */

short s_port; /* Æ÷Æ®¹øÈ£ */

char FAR * s_proto; /* ÇÁ·ÎÅäÄÝ Á¾·ù */

};

 

WSAAsyncGetServByName()ÀÇ »ç¿ë ¹®¹ýÀº ´ÙÀ½°ú °°´Ù.

HANDLE WSAAsyncGetServByName (

HWND Hwnd, /* ÀÌ ÇÔ¼öÀÇ ¸Þ½ÃÁö¸¦ ¼ö½ÅÇÒ À©µµ¿ì ÇÚµé */

unsigned int Msg, /* ÀÌ ÇÔ¼ö Á¾·á½Ã Àü¼ÛÇÒ ¸Þ½ÃÁö */

const char *name, /* Æ÷Æ®¹øÈ£¸¦ ¾Ë°íÀÚ ÇÏ´Â ¼­ºñ½º À̸§ */

const char *proto, /* TCP³ª UDP¸¦ ÁöÁ¤(¶Ç´Â NULL) */

char *buf, /* servent ±¸Á¶Ã¼ÀÇ Æ÷ÀÎÅÍ */

int buflen); /* bufÀÇ ±æÀÌ */

 

ÀÌ ÇÔ¼öÀÇ »ç¿ë ¿¹·Î UDP ÇÁ·ÎÅäÄÝ·Î ±¸ÇöµÈ time ¼­ºñ½ºÀÇ Æ÷Æ®¹øÈ£¸¦ ã¾Æ³»¾î È­¸é¿¡ Ãâ·ÂÇÏ´Â ¿¹¸¦ ¾Æ·¡¿¡ º¸¿´´Ù. ¿©±â¼­ PSERVENT´Â servent ±¸Á¶Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ Å¸ÀÔÀ» ¸»ÇÑ´Ù.

PSERVENT m_pservent; /* servent ±¸Á¶Ã¼ Æ÷ÀÎÅÍ */

char m_lpszMsg[100]; /* È­¸é¿¡ Ãâ·ÂÇÒ ¸Þ½ÃÁö ¹öÆÛ */

char m_lpszServEntryBuf[MAXGETHOSTSTRUCT];

WSAAsyncGetServByName(m_hWnd, WM_USER_ASYNCGETSERVBYNAME, "time",

"udp", m_lpszServEntryBuf, MAXGETHOSTSTRUCT) ;

m_pservent = (PSERVENT)m_lpszServEntryBuf;

wsprintf(m_lpszMsg, "%s ¼­ºñ½º Æ÷Æ® : %d", m_pservent->s_name,

m_pservent->s_port);

 

          2-3-3. WSAAsyncGetHostByName()

ÀÌ ÇÔ¼ö´Â È£½ºÆ® À̸§À» »ç¿ëÇÏ¿© IP ÁÖ¼Ò¸¦ ã¾Æ³»´Â ÇÔ¼öÀÌ¸ç »ç¿ë ¹®¹ýÀº ¾Æ·¡¿Í °°´Ù.

HANDLE WSAAsyncGetHostByName (

HWND hwnd, /* ¸Þ½ÃÁö¸¦ ¼ö½ÅÇÒ À©µµ¿ì ÇÚµé */

unsigned int wMsg, /* ¼ö½ÅÇÒ ¸Þ½ÃÁö */

char FAR *name, /* ãÀ» È£½ºÆ® ³×ÀÓÀÇ Æ÷ÀÎÅÍ */

char FAR *buf, /* °á°ú°¡ ¸®ÅϵǴ ¹öÆÛÀÇ Æ÷ÀÎÅÍ */

int bufflen

); /* ¹öÆÛÀÇ ±æÀÌ */

 


 

3. À©¼Ó ÇÁ·Î±×·¥ ¼­¹ö(Not Using MFC)

     3-1. ChatServer.cpp

/***********************************************************************/

/* ChatServer.cpp (winsocket ±âº»¿¹Á¦ Not Using MFC) */

/* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.18 */

/***********************************************************************/

#include <winsock2.h>

#include <iostream.h>

#define MAXLINE 512

#define DEFAULT_BUFFER 4096

DWORD WINAPI ClientThread(LPVOID lpParam)

{

SOCKET sock = (SOCKET)lpParam;

char szBuff[DEFAULT_BUFFER];

char *sMessage = "Server : Success Connecting";

int ret, senddata;

 

ret = recv (sock, szBuff, DEFAULT_BUFFER, 0);

 

if(ret == SOCKET_ERROR)

{

cout << "Thread Socket : Recv() failed : " << WSAGetLastError() << endl;

return 0;

}

szBuff[ret] = '\0';

 

cout << "[Server] RECV : " << szBuff << endl;

senddata = send (sock, sMessage, strlen(sMessage), 0);

if(senddata == SOCKET_ERROR)

{

cout << "Thread Socket : Send() failed : "<< WSAGetLastError() << endl;

return 0;

}

return 0;

}

int main ()

{

WSADATA wsd;

SOCKET Rsock;

SOCKET Csock;

HANDLE hThread;

DWORD dwThreadId;

int iAddrSize;

struct sockaddr_in local; //Server socket address struct

struct sockaddr_in client; //Client socket address struct

//winsock library initialize

if(WSAStartup(MAKEWORD(2,2), &wsd) != 0)

{

cout << "[Server] : Failed to load winsock library" << endl;

return -1;

}

else cout << "[Server] : Server WSAStartup"<< endl;

 

//listen socket create

Rsock = socket(AF_INET, SOCK_STREAM, 0);

if(Csock == SOCKET_ERROR)

{

cout << "[Server] : Socket create fail : " << WSAGetLastError();

return -1;

}

else cout << "[Server] : Socket Created" << endl;

 

//sockaddr_in description

local.sin_family = AF_INET;

local.sin_addr.s_addr = htonl(INADDR_ANY);

local.sin_port = htons(8198);

if(bind (Rsock, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)

{

cout << "[Server] : Bind fail : " << WSAGetLastError();

return -1;

}

cout << "[Server] : Socket Bind" << endl;

listen (Rsock, 8);

cout << "[Server] : Listen" << endl;

while(1)

{

iAddrSize = sizeof(client);

Csock = accept (Rsock, (struct sockaddr *)&client, &iAddrSize);

if (Csock == INVALID_SOCKET)

{

cout << "[Server] : Accept fail : " << WSAGetLastError();

break;

}

cout << "[Server] : Accept client : " << inet_ntoa(client.sin_addr) << " : " << ntohs(client.sin_port) << endl;

hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)Csock, 0, &dwThreadId);

 

if(hThread == NULL)

{

cout << "[Server] : CreateThread() failed : " << GetLastError() << endl;

break;

}

CloseHandle(hThread);

}

closesocket(Csock);

cout << "[Server] : Close Csock" << endl;

closesocket(Rsock);

cout << "[Server] : Close Rsock" << endl;

WSACleanup();

cout << "[Server] : WSACleanup" << endl;

return 0;

}

 

      3-2. ChatClient.cpp

/***********************************************************************/

/* ChatClient.cpp (winsocket ±âº»¿¹Á¦ Not Using MFC) */

/* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.18 */

/***********************************************************************/

#include <winsock2.h>

#include <iostream.h>

#define MAXLINE 512

int main ()

{

WSADATA wsd;

SOCKET Csock;

struct sockaddr_in server;

struct hostent *host = NULL;

char sServerIP[128], sendline[MAXLINE], recvline[MAXLINE];

int senddata, recvdata, iPort;

//winsocket library ¸¦ load ÇÔ

if (WSAStartup (MAKEWORD (2, 2), &wsd) != 0)

{

cout << "[Client] : Failed to load winsock library" << endl;

return -1;

}

else cout << "[Client] : Client WSAStartup"<< endl;

//client socket Create

Csock = socket (AF_INET, SOCK_STREAM, 0);

if (Csock == INVALID_SOCKET)

{

cout << "[Client] : Socket create fail : " << WSAGetLastError ();

return -1;

} else cout << "[Client] : Socket created" << endl;

 

cout << "Input Connect Server IP : ";

//Ç¥ÁØ ÀÔ·Â - server program¿¡ Á¢¼ÓÇÒ IP Address

cin.getline(sServerIP, 128);

cout << "Input Connect Server Port Number : ";

//server program¿¡ Á¢¼ÓÇÒ port

cin >> iPort;

//sockaddr_in description

server.sin_family = AF_INET;

server.sin_addr.s_addr = inet_addr(sServerIP);

server.sin_port = htons(iPort);

 

//server program°ú Á¢¼ÓÀ» ¼öÇà

if(connect(Csock, (struct sockaddr*)&server, sizeof(server)) ==

SOCKET_ERROR)

{

cout << "[Client] : Connect fail : " << WSAGetLastError();

return -1;

}

else cout << "[Client] : Connect success" << endl;

 

cout << "Input SendMessage : ";

cin >> sendline;

//message send to server

senddata = send(Csock, sendline, strlen(sendline), 0);

//message Àü´Þ ½Ã ¿¡·¯Ã³¸®

if(senddata == SOCKET_ERROR)

{

cout << "[Client] : Send fail : " << WSAGetLastError();

return -1;

} else {

cout << "[Client] : Send success" << endl;

cout << "[Client] : Send [" << senddata << "bytes]" << endl;

}

//server·Î ºÎÅÍ data¹ÞÀ½

recvdata = recv(Csock, recvline, MAXLINE, 0);

 

//server·Î ¹ÞÀ» µ¥ÀÌÅÍ ¿¡·¯

if(recvdata == SOCKET_ERROR)

{

cout << "[Client] : Receive fail : " << WSAGetLastError();

return -1;

} else {

recvline[recvdata] = '\0';

cout << "[Client] : Receive success" << endl;

cout << "[Client] : Receive [" << recvdata << "bytes] : " << recvline << endl;

}

//client socket close

closesocket (Csock);

cout << "[Client] : Csock Close" << endl;

WSACleanup ();

cout << "[Client] : WSACleanup" << endl;

return 0;

}

 


 

4. À©¼Ó äÆà ¼­¹ö(Use MFC in a Shared DLL)

äÆà ¼­¹ö¿Í Ŭ¶óÀ̾ðÆ®ÀÇ ¿¬°á°ü°è ±×¸®°í ¼­¹ö¿¡¼­ »ç¿ëÇÏ´Â ¼ÒÄÏÀÇ Á¾·ù(m_sAccept¿Í m_sClient[])¸¦ ±×¸² 5-1¿¡ ³ªÅ¸³Â´Ù.

±×¸² 5-1 À©¼Ó äÆà ¼­¹ö¿Í À©¼Ó äÆà Ŭ¶óÀ̾ðÆ®ÀÇ ¿¬°á°ü°è

(m_sAccept:Ãʱâ¼ÒÄÏ, m_sClient[]: äÆà Âü°¡ÀÚÀÇ ¼ÒÄϹøÈ£ ¹è¿­)

 

äÆà ¼­¹ö´Â Ŭ¶óÀ̾ðÆ®ÀÇ Á¢¼Ó¿äûÀ» ¼ö¶ôÇÏ´Â ÀÏ°ú ¾î¶² Ŭ¶óÀ̾ðÆ®°¡ º¸³»¿Â ¸Þ½ÃÁö¸¦ ¸ðµç Ŭ¶óÀ̾ðÆ®¿¡°Ô ¹æ¼ÛÇÏ´Â µÎ °¡Áö ÀÏÀ» ¼öÇàÇÑ´Ù. À̸¦ À§ÇÏ¿© ¼­¹ö´Â µÎ °¡Áö Á¾·ùÀÇ ¼ÒÄÏÀ» ÇÊ¿ä·Î Çϴµ¥ ù ¹ø°´Â Á¢¼Ó¿äûÀ» ±â´Ù¸®´Â ¼ÒÄÏ(m_sAccept)À̸ç, µÎ ¹ø°´Â äÆÿ¡ Âü°¡ÇÏ´Â °¢ Ŭ¶óÀ̾ðÆ®µé°ú ¸Þ½ÃÁö¸¦ ÁÖ°í¹Þ±â À§ÇÑ ¼ÒÄÏÀÌ´Ù.

À̸¦ À§ÇÏ¿© ¼ÒÄÏÀÇ ¹è¿­(m_sClient[])À» »ç¿ëÇÑ´Ù.

¼­¹ö´Â ¸ÕÀú Ãʱâ¼ÒÄÏ(m_sAccept)À» »ý¼ºÇÏ°í ¿©±â¿¡ accept()¸¦ È£ÃâÇØ µÐ´Ù. ÀÌ ¼ÒÄÏÀ¸·Î ¾î¶² Ŭ¶óÀ̾ðÆ®°¡ äÆÿ¡ Âü°¡Çϱ⸦ ½ÅûÇϸé accept()°¡ 󸮵ǰí, accept()°¡ ¸®ÅÏ ÇÑ »õ·Î¿î ¼ÒÄϹøÈ£¸¦ ¹è¿­ m_sClient[]¿¡ Â÷·Ê·Î ÀúÀåÇÏ°Ô µÈ´Ù.

±×¸² 5-2´Â ¼­¹ö ÇÁ·Î±×·¥ÀÇ ½ÇÇà ¿¹ÀÌ´Ù. ¼­¹ö ÇÁ·Î±×·¥ WChat_Server.cÀÇ Àüü ¸®½ºÆ®´Â 5.3.2Àý¿¡ ¼ö·ÏµÇ¾î ÀÖÀ¸¸ç ¸ÕÀú ÇÁ·Î±×·¥ÀÇ ÁÖ¿äºÎºÐÀ» ¼³¸íÇÏ°Ú´Ù.

±×¸² 5-2 À©¼Ó ¼­¹ö ÇÁ·Î±×·¥ ½ÇÇà È­¸é

 

     4-1. ÇÁ·Î±×·¥ ÁÖ¿äºÎºÐ ¼³¸í

 

            4-1-1. Çì´õ ÆÄÀÏ

Server.h ÆÄÀÏÀº ±×¸² 5-2¿Í °°Àº È­¸éÀ» ±¸¼ºÇÏ´Â Á¤º¸¸¦ °¡Áö°í ÀÖ´Â ÆÄÀÏ·Î ¿©±â ¿¡¼­´Â Visual C·Î ÀÛ¼ºÇÏ¿´´Ù.

#include <windows.h> /* À©µµ¿ì ÀÀ¿ë ÇÁ·Î±×·¥ÀÇ ¸¶½ºÅÍ Çì´õ ÆÄÀÏ */

#include <Winsock.h> /* À©¼Ó °ü·Ã »ó¼ö ¹× ÇÔ¼ö ¼±¾ð */

#include "Server.h" /* ¸®¼Ò½º ÆÄÀÏ */

 

          4-1-2. Àü¿ª º¯¼ö

äÆà ¼­¹ö ÇÁ·Î±×·¥¿¡¼­ »ç¿ëÇÏ´Â Àü¿ª º¯¼ö¿Í °¢°¢ÀÇ ±â´ÉÀº ´ÙÀ½°ú °°´Ù.

SOCKET m_sAccept; /* äÆà Âü°¡½ÅûÀ» ¹Þ±â À§ÇÑ ¼ÒÄÏ */

SOCKET m_sClient[]; /* °¢ Ŭ¶óÀ̾ðÆ®¿Í ¸Þ½ÃÁö¸¦ ÁÖ°í¹Þ±â À§ÇÑ ¼ÒÄÏ ¹è¿­ */

char m_strMsg[]; /* ¸Þ½ÃÁö¸¦ ÀúÀåÇÒ ¹öÆÛ */

int m_Total; /* äÆÿ¡ Âü°¡ÇÏ°í Àִ Ŭ¶óÀ̾ðÆ® ¼ö */

HWND hWnd; /* À©µµ¿ì ÇÚµé */

 

           4-1-3. WinMain() ÇÔ¼ö

º» ¿¹Á¦¿¡¼­´Â À©µµ¿ì ´ëÈ­»óÀÚ(DialogBox)¸¦ ¸ÞÀÎ À©µµ¿ì·Î »ç¿ëÇÏ°í ÀÖ´Ù.

¾Æ·¡ÀÇ ÄÚµå´Â WinMain() Áß¿¡¼­ CreateDialog()·Î ´ëÈ­»óÀÚ¸¦ »ý¼ºÇÏ°í, GetMessage()·Î ´ëÈ­»óÀÚ¿¡ µµÂøÇÏ´Â ¸Þ½ÃÁö¸¦ ¹Þ¾Æ À̸¦ ó¸®ÇÏ´Â ·çÇÁ¸¦ º¸ÀÌ°í ÀÖ´Ù.

 

if((hWnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_SERVER),

NULL, HandleDialog)) == NULL) {

MessageBox(NULL, "ÃʱâÈ­ ¿¡·¯", "È®ÀÎ", MB_OK);

return FALSE;

}

while(GetMessage(&msg, NULL, 0, 0)) {

if(!IsDialogMessage(hWnd, &msg)) {

TranslateMessage(&msg); /* ¸Þ½ÃÁö Å¥¿¡¼­ ¸Þ½ÃÁö¸¦ °¡Áö°í ¿È */

DispatchMessage(&msg); /* ¸Þ½ÃÁö¸¦ ºÐ¼®ÇÑ´Ù */

}

}

 

           4-1-4. ¸Þ½ÃÁö ó¸®

WChat_Server.c¿¡¼­ ó¸®ÇØ¾ß ÇÒ ¸Þ½ÃÁö´Â ¾Æ·¡¿Í °°ÀÌ ³× °¡ÁöÀÌ¸ç °¢ ¸Þ½ÃÁö°¡ ¹ß»ýÇÏ´Â Á¶°ÇÀº ´ÙÀ½°ú °°´Ù. WM_INITDIALOG: ´ÙÀ̾ó·Î±× ¹Ú½º°¡ »ý¼ºµÉ ¶§ ¹ß»ýÇϴµ¥ WChat_Server.c¿¡¼­´Â ÀÌ ¸Þ½ÃÁö°¡ ¹ß»ýÇϸé Àü¿ª º¯¼öµé°ú À©¼ÓÀ» ÃʱâÈ­ÇÑ ÈÄ Å¬¶óÀ̾ðÆ®ÀÇ ¿¬°á¿äûÀ» ±â´Ù¸®±â À§ÇØ »ç¿ëÀÚ Á¤ÀÇ ÇÔ¼öÀÎ InitSocket()À» È£ÃâÇÑ´Ù.

WM_COMMAND : ¸Þ´º, ¸®½ºÆ®¹Ú½º, ¹öÆ°, üũ¹Ú½º µî¿¡¼­ ¹ß»ýÇÏ´Â ¸Þ½ÃÁö·Î

WChat_Server.c¿¡¼­´Â »ç¿ëÀÚ°¡ Á¾·á¹öÆ°À» Ŭ¸¯ÇÒ ¶§¸¸ ¹ß»ýÇÑ´Ù.

WM_DESTROY : À©µµ¿ì°¡ Á¾·áµÉ ¶§ ³»ºÎÀûÀ¸·Î ¹ß»ýÇÑ´Ù.

WM_ASYNC : WChat_Server.c¿¡¼­ Á¤ÀÇÇÑ ¸Þ½ÃÁö·Î ¼ÒÄÏÀ» ÅëÇÏ¿© µ¥ÀÌÅ͸¦

ºñµ¿±â ¸ðµå·Î ó¸®ÇÏ´Â µ¥ »ç¿ëµÈ´Ù.

¸Þ½ÃÁöÀÇ Ã³¸®´Â HandleDialog() ÇÔ¼ö¿¡¼­ ÀÌ·ç¾îÁö´Âµ¥ HandleDialog()°¡ ÇÔ¼ö ÀÎÀÚ·Î ¸®ÅÏÇÏ´Â ¸Þ½ÃÁö iMsgÀÇ Á¾·ù¿¡ µû¶ó ÇØ¾ß ÇÒ ÀÏÀ» ´ÙÀ½°ú °°ÀÌ ±¸ºÐÇÑ´Ù.

BOOL CALLBACK HandleDialog(HWND hWnd, UINT iMsg, WPARAM wParam,

LPARAM lParam) {

switch(iMsg) {

case WM_INITDIALOG:

/* Àü¿ª º¯¼ö ¹× À©¼Ó ÃʱâÈ­ */

case WM_COMMAND:

/* "Á¾·á" ¹öÆ° ÀԷ ó¸® */

case WM_DESTROY:

/* ÇÁ·Î±×·¥ Á¾·á */

case WM_ASYNC:

/* ºñµ¿±â ¸Þ½ÃÁö ó¸® */

}

}

 

           4-1-5. WM_INITDIALOGÀÇ Ã³¸®

WChat_Server.c¿¡¼­´Â WM_INITDIALOG ¸Þ½ÃÁö°¡ ¹ß»ýÇÏ¸é »ç¿ëÀÚ Á¤ÀÇ ÇÔ¼öÀÎ InitSocket()À» È£ÃâÇϵµ·Ï ÇÏ¿´´Ù. InitSocket() ÇÔ¼ö¿¡¼­´Â WSAStartup() ½Ã½ºÅÛ ÄÝÀ» È£ÃâÇÏ¿© Winsock.dllÀ» ÃʱâÈ­ÇÑ´Ù. À©¼Ó¿¡¼­µµ ¼ÒÄÏÀÇ »ý¼ºÀº BSD ¼ÒÄÏ¿¡¼­¿Í °°ÀÌ socket() ÇÔ¼ö¸¦ ÅëÇؼ­ ÀÌ·ç¾îÁø´Ù

¾Æ·¡´Â ¼ÒÄÏÀ» ¸¸µé°í ¼ÒÄϹøÈ£(m_sAccept)¿Í ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ serv_addr¸¦ bind()ÇÑ ÈÄ listen()À» È£ÃâÇÏ´Â °ÍÀ» º¸ÀÌ°í ÀÖ´Ù.

#define CHAT_PORT 7001 /* Æ÷Æ®¹øÈ£·Î 7001¹ø »ç¿ë */

m_sAccept = socket(AF_INET, SOCK_STREAM, 0);

serv_addr.sin_family = AF_INET;

serv_addr.sin_port = htons(CHAT_PORT);

serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

bind(m_sAccept, (LPSOCKADDR)&serv_addr, sizeof(serv_addr));

listen(m_sAccept, 5);

 

           4-1-6. WM_COMMANDÀÇ Ã³¸®

WM_COMMAND ¸Þ½ÃÁö´Â »ç¿ëÀÚ°¡ ¹öÆ°, ¸®½ºÆ®¹Ú½º, üũ¹Ú½º, ¿¡µðÆ®¹Ú½º, ¸Þ´º µîÀ» »ç¿ëÇÒ ¶§ ¹ß»ýÇÏ´Â ¸Þ½ÃÁöÀÌ´Ù. ÀÌ ÇÁ·Î±×·¥¿¡¼­´Â "Á¾·á" ¹öÆ°ÀÌ ´­¸± ¶§ ¹ß»ýÇÏ´Â ¸Þ½ÃÁö¸¸ ó¸®ÇÏ¸é µÈ´Ù.

¾Æ·¡ÀÇ WM_COMMAND 󸮺κп¡¼­ wParamÀº À§¿¡ ¿­°ÅÇÑ °Í°ú °°Àº ¿©·¯ Á¾·ùÀÇ ¸Þ

½ÃÁö¸¦ ±¸ºÐÇÏ´Â ÆĶó¹ÌÅÍÀ̸ç IDC_EXIT´Â Á¾·á ¹öÆ°ÀÇ IDÀÌ´Ù.

ÇÑÆí DestroyWindow() ÇÔ¼ö´Â À©µµ¿ì ³»ºÎ¿¡ WM_ DESTROY ¸Þ½ÃÁö¸¦ º¸³»ÁØ´Ù.

case WM_COMMAND:

switch(wParam) {

case IDC_EXIT:

DestroyWindow(hWnd);

return TRUE;

}

 

          4-1-7. WM_DESTROYÀÇ Ã³¸®

WM_DESTROY´Â (À§ÀÇ DestroyWindow()¿¡ ÀÇÇØ) À©µµ¿ì¿¡¼­ ³»ºÎÀûÀ¸·Î ¹ß»ýµÇ´Â ¸Þ½ÃÁö·Î À©µµ¿ì¸¦ Á¾·á½Ãų ¶§ »ç¿ëµÈ´Ù. ´ÙÀ½ÀÇ Äڵ忡¼­ PostQuitMessage()´Â À©µµ¿ì ¸Þ½ÃÁö Å¥¿¡ Á¾·á ¸Þ½ÃÁö¸¦ Àü¼ÛÇÏ´Â ÇÔ¼öÀÌ´Ù.

case WM_DESTROY:

PostQuitMessage(0);

return TRUE;

 

          4-1-8. WM_ASYNCÀÇ Ã³¸®

À©¼Ó¿¡¼­´Â ¼ÒÄÏÀÌ ºí·ÎÅ· ¸ðµå·Î µ¿ÀÛÇÒ ¶§ÀÇ ¹®Á¦Á¡À» ÇØ°áÇϱâ À§Çؼ­ WSAAsyncSelect() ÇÔ¼ö¸¦ Á¦°øÇÑ´Ù.

WChat_Server.c¿¡¼­´Â WSAAsyncSelect()°¡ WM_ASYNC¶ó´Â ¸Þ½ÃÁö¸¦ ¹ß»ý½ÃÅ°µµ·Ï ÇÏ¿´´Ù. WChat_Server.c¿¡¼­´Â ºñµ¿±â ¸ðµå·Î I/O¸¦ ó¸®Çϱâ À§ÇÏ¿© WSAAsyncSelect()¸¦ ¾Æ·¡¿Í °°ÀÌ µÎ °¡Áö ¼ÒÄÏ¿¡ ´ëÇÏ¿© °¢°¢ È£ÃâÇØ¾ß ÇÑ´Ù.

1) accept()¸¦ ºñµ¿±âÀûÀ¸·Î ó¸®Çϱâ À§ÇÏ¿© Ãʱâ¼ÒÄÏ(m_sAccept)¿¡ ´ëÇÏ¿© È£ÃâÇÏ´Â °Í.

2) °¢ Ŭ¶óÀ̾ðÆ®µé°ú äÆà ¸Þ½ÃÁö¸¦ ºñµ¿±âÀûÀ¸·Î ¼Û¼ö½ÅÇϱâ À§ÇÏ¿© ¼ÒÄÏ ¹è¿­ m_sClient[]¿¡ ´ëÇÏ¿© È£ÃâÇÏ´Â °Í.

1)¹øÀÇ °æ¿ì WSAAsyncSelect()¸¦ È£ÃâÇÏ´Â °ÍÀ» ¾Æ·¡¿¡ º¸¿´´Ù.

m_sAccept´Â FD_ACCEPT À̺¥Æ® ¹ß»ýÀ» °¨½ÃÇÒ Ãʱâ¼ÒÄÏÀÇ ¹øÈ£ÀÌ°í m_hWnd´Â FD_ACCEPT À̺¥Æ®°¡ ¹ß»ýÇßÀ» ¶§ ¸Þ½ÃÁö¸¦ ¹ÞÀ» À©µµ¿ì ÇÚµéÀ̸ç, WM_ASYNC´Â Àü¼ÛÇÒ ¸Þ½ÃÁö¸¦ ³ªÅ¸³½´Ù.

WSAAsyncSelect(m_sAccept, hWnd, WM_ASYNC, FD_ACCEPT);

 

2)¹øÀÇ °æ¿ì´Â »õ·Î¿î äÆà Ŭ¶óÀ̾ðÆ®°¡ Ãß°¡·Î ¿¬°áµÉ ¶§ Áï, accept()°¡ ¼º°øÀûÀ¸·Î ¼öÇàµÇ¾úÀ» ¶§ accept()°¡ ¸®ÅÏÇÑ ¼ÒÄϹøÈ£ m_sClient[m_Total]¿¡ ´ëÇÏ¿© ¼öÇàµÈ´Ù(m_TotalÀº ÇöÀç äÆÿ¡ Âü°¡ÇÑ ÃÑ »ç¶÷¼ö).

±×·¯³ª 2)ÀÇ °æ¿ì´Â 1)ÀÇ °æ¿ì¿Í ´Þ¸® °¢ Ŭ¶óÀ̾ðÆ®¿ÍÀÇ µ¥ÀÌÅÍÀÇ ¼Û½Å, ¼ö½Å, Á¾·á µî ¼¼ °¡Áö À̺¥Æ®¸¦ ó¸®ÇÏ¿©¾ß ÇϹǷΠFD_ACCEPT°¡ ¾Æ´Ï¶ó FD_READ|FD_WRITE| FD_CLOSE¸¦ À̺¥Æ® ¸®½ºÆ®·Î ÁöÁ¤ÇÏ¿©¾ß ÇÑ´Ù.

¾Æ·¡´Â ÀÌ·¯ÇÑ ±â´ÉÀ» ¼öÇàÇÏ´Â ÇÁ·Î±×·¥ ÄÚµåÀÌ¸ç ¿©±â¼­ msg¿¡´Â ¸ðµç äÆà °¡ÀÔÀÚ¿¡°Ô º¸³»´Â ¸Þ½ÃÁö°¡ ÀúÀåµÈ´Ù.

 

cli_len = sizeof(cli_addr);

m_sClient[m_Total] = accept(m_sAccept, (LPSOCKADDR)&cli_addr, &cli_len);

WSAAsyncSelect(m_sClient[m_Total], m_hWnd, WM_ASYNC,

FD_READ|FD_WRITE|FD_CLOSE);

wsprintf(msg, "%d¹ø° Ŭ¶óÀ̾ðÆ® Ãß°¡", m_Total);

m_Total++;

 

WSAAsyncSelect()¸¦ È£ÃâÇØ µÐ ÀÌÈÄ¿¡ WM_ASYNC ¸Þ½ÃÁö°¡ ¹ß»ýÇÏ¸é ¾î´À ¼ÒÄÏ¿¡¼­ ÀÌ ¸Þ½ÃÁö¸¦ ¹ß»ý½ÃÄ×´ÂÁö¸¦ ¾Ë¾Æ³»¾ß ÇÑ´Ù.

¾Æ·¡´Â ÀÌ·¯ÇÑ ±â´ÉÀ» ó¸®ÇÏ´Â ÇÁ·Î±×·¥ ÄÚµåÀε¥, WM_ ASYNC ¸Þ½ÃÁö¸¦ ¹ß»ý½ÃŲ ¼ÒÄÏÀÌ ¾î¶² ¼ÒÄÏÀÎÁö È®ÀÎÇϱâ À§ÇÏ¿© Àӽà ¼ÒÄϹøÈ£ sock_tmp¸¦ »ç¿ëÇÏ°í ÀÖ´Ù.

SOCKET sock_tmp;

case WM_ASYNC:

sock_tmp = LOBYTE(wParam); /* À̺¥Æ®¸¦ ¹ß»ý½ÃŲ ¼ÒÄϹøÈ£ ÃßÃâ */

if(sock_tmp == m_sAccept) {

/* »õ·Î¿î Ŭ¶óÀ̾ðÆ®ÀÇ Âü°¡½Åû ó¸® Áï accept() ¼öÇà */

} else {

/* m_sClient[] Áß¿¡ ÇØ´ç Ŭ¶óÀ̾ðÆ®ÀÇ Ã¤Æà ¸Þ½ÃÁö ¼ö½Å */

/* äÆà ¸Þ½ÃÁö ¹æ¼Û */

}

 

          4-1-9. µ¥ÀÌÅÍ ¼Û¼ö½Å

WSAAsyncSelect()¿¡¼­ ÁöÁ¤ÇÑ »ç¿ëÀÚ ¸Þ½ÃÁö WM_ASYNC°¡ ¹ß»ýÇÏ¿´À» ¶§ ¼ÒÄÏ¿¡¼­ ¹ß»ýÇÑ À̺¥Æ®ÀÇ ±¸Ã¼ÀûÀÎ ³»¿ëÀÌ lParam ÆĶó¹ÌÅÍ¿¡ µé¾î ÀÖ°Ô µÈ´Ù. µû¶ó¼­ lParamÀÇ °ªÀ» È®ÀÎÇÏ¿© µ¥ÀÌÅÍÀÇ ¼Û½Å ¹× ¼ö½Å µîÀÇ ÀûÀýÇÑ ±â´ÉÀ» ó¸®ÇÏ¸é µÈ´Ù. ´ÙÀ½¿¡ µ¥ÀÌÅÍ Àбâ, ¾²±â, Á¾·á À̺¥Æ®¸¦ °¢°¢ ó¸®ÇÏ´Â °ÍÀ» º¸ÀÌ°í ÀÖ´Ù.

switch(lParam) {

case FD_READ: /* ÀÐÀ» µ¥ÀÌÅÍ ¹ß»ý */

/* Ŭ¶óÀ̾ðÆ®°¡ º¸³½ µ¥ÀÌÅ͸¦ Àд´٠*/

memset(buf, '\0', 512);

recv_len = recv(sock_tmp, buf, 512, 0);

/* ¼ÒÄÏ(sock_tmp)¿¡ FD_WRITEÀÇ »ç¿ëÀÚ Á¤ÀÇ ¸Þ½ÃÁö¸¦ ¹ß»ý½ÃŲ´Ù. */

PostMessage(WM_ASYNC, sock_tmp,

WSAMAKESELECTREPLY(FD_WRITE,0));

break;

case FD_WRITE: /* ¸ðµç äÆà °¡ÀÔÀÚ¿¡°Ô ¸Þ½ÃÁö¸¦ Àü¼ÛÇÑ´Ù */

for(i=0; i<m_Total; i++) send(m_sClient[i], buf, sizeof(buf), 0);

break;

case FD_CLOSE: /* ÇØ´ç Ŭ¶óÀ̾ðÆ®¸¦ Á¾·á½ÃÅ°°í */

/* Àüü Ŭ¶óÀ̾ðÆ® ¼ö¸¦ Çϳª ÁÙÀδ٠*/

for(i = 0; i < m_Total; i++) {

if (sock_tmp == m_sClient[i]) { /* Á¾·á¸¦ ¿øÇÏ´Â ¼ÒÄÏÀÌ */

/* Ŭ¶óÀ̾ðÆ® ¼ÒÄÏ ¹è¿­¿¡ ÀÖ´ÂÁö È®ÀÎ */

closesocket(m_sClient[i]);

/* ¼ÒÄÏ ¹è¿­ÀÇ ºó °÷À» ä¿î´Ù */

if ( i != (m_Total - 1) ) {

m_sClient[i] = m_sClient[m_Total-1];

}

m_Total--;

break;

}

}

}

ÀÌ»óÀÌ wchat_server ÇÁ·Î±×·¥ ¼Ò½º ¼³¸íÀÌ´Ù.


 

5. À©¼Ó äÆà Ŭ¶óÀ̾ðÆ®(Use MFC in a Shared DLL)

À©¼Ó äÆà Ŭ¶óÀ̾ðÆ® ÇÁ·Î±×·¥ WChat_Client.c´Â »ç¿ëÀÚ°¡ Å°º¸µå¿¡¼­ ÀÔ·ÂÇÑ ¹®ÀÚ¿­À» ¼­¹ö¿¡°Ô Àü¼ÛÇÏ°í ¼­¹ö°¡ º¸³»¿Â ¸Þ½ÃÁö¸¦ È­¸é¿¡ Ãâ·ÂÇÏ´Â ±â´ÉÀ» ¼öÇàÇÑ´Ù.

±×¸² 5-3Àº äÆà Ŭ¶óÀ̾ðÆ® ÇÁ·Î±×·¥ÀÇ ½ÇÇà ¿¹ÀÌ´Ù (±×¸² 5-3À» ±¸¼ºÇÏ´Â ¸®¼Ò½º ÆÄÀÏ Client.rc´Â Visual C·Î ÀÛ¼ºÇÏ¿´´Ù).

±×¸² 5-3 äÆà Ŭ¶óÀ̾ðÆ® ÇÁ·Î±×·¥ ½ÇÇà ¿¹

 

     5-1. ÇÁ·Î±×·¥ ÁÖ¿äºÎºÐ ¼³¸í

 

          5-1-1. Çì´õ ÆÄÀÏ°ú Àü¿ªº¯¼ö

WChat_Client.c´Â ´ÙÀ½°ú °°Àº Çì´õ ÆÄÀÏ°ú Àü¿ªº¯¼ö¸¦ ÇÊ¿ä·Î ÇÑ´Ù.

#include <windows.h> /* À©µµ¿ì ÀÀ¿ë ÇÁ·Î±×·¥ÀÇ ¸¶½ºÅÍ Çì´õ ÆÄÀÏ */

#include <stdlib.h> /* ¹®ÀÚ Ã³¸®¸¦ À§ÇÑ Çì´õ ÆÄÀÏ */

#include <Winsock.h> /* À©¼Ó °ü·Ã »ó¼ö ¹× ÇÔ¼ö ¼±¾ð */

#include "Client.h" /* ¸®¼Ò½º ÆÄÀÏ */

HINSTANCE hInst; /* ÇöÀç À©µµ¿ìÀÇ ÀνºÅϽº */

WNDPROC OldProc; /* ¼­ºêŬ·¡½ÌÀ» Çϱâ À§ÇØ ÀúÀåÇÒ ±âÁ¸ÀÇ ÇÁ·Î½ÃÁ® */

char msg[512]; /* ÀÔÃâ·Â¿ë µ¥ÀÌÅÍ */

SOCKET m_s; /* ¼ÒÄϹøÈ£ */

SOCKADDR_IN m_addr; /* ÀÎÅÍ³Ý Å¸ÀÔÀÇ ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ */

HWND hParent; /* Parent À©µµ¿ìÀÇ ÇÚµé */

 

          5-1-2. WM_INITDIALOGÀÇ Ã³¸®

À©µµ¿ì°¡ óÀ½ »ý¼³ µÉ ¶§ ¹ß»ýÇÏ´Â ¸Þ½ÃÁöÀÎ WM_ INITDIALOGÀÇ Ã³¸®ºÎ¿¡¼­´Â ´ÙÀ½°ú °°ÀÌ À©¼ÓÀÇ ÃʱâÈ­(InitSocket())¿Í ´ÙÀ½¿¡ ¼³¸íÇÑ ¿¡µðÆ® ÄÁÆ®·Ñ ¼­ºêŬ·¡½Ì(subclassing)À» ¼öÇàÇÑ´Ù.

case WM_INITDIALOG:

memset(msg, '\0', sizeof(msg));

if(!InitSocket(hWnd))

return FALSE;

OldProc = (WNDPROC) SetWindowLong (GetDlgItem(hWnd, IDC_EDIT),

GWL_WNDPROC, (LONG)EditProc);

return TRUE;

 

          5-1-3. ¼­ºêŬ·¡½Ì

Ŭ¶óÀ̾ðÆ® ÇÁ·Î±×·¥Àº ´ÙÀ̾ó·Î±× ¹Ú½º·ÎºÎÅÍ ½ÇÇàÀÌ ½ÃÀ۵Ǵµ¥ ¿¡µðÆ® ÄÁÆ®·Ñ(edit control)À» ÅëÇÏ¿© µ¥ÀÌÅ͸¦ ÀԷ¹޴´Ù. ¿¡µðÆ® ÄÁÆ®·Ñ¿¡¼­´Â »ç¿ëÀÚ°¡ ¸®ÅÏ('\n')±îÁö ÀÔ·ÂÇÑ ¹®ÀÚ¿­À» ¹Þ¾Æ, »ç¿ëÀÚ Á¤ÀÇ ¸Þ½ÃÁöÀÎ WM_ASYNC¸¦ ÀÌ¿ëÇÏ¿© ó¸®ÇÑ´Ù. À̸¦ À§ÇÏ¿© ¼­ºêŬ·¡½ÌÀ» »ç¿ëÇÑ´Ù.

¼­ºêŬ·¡½ÌÀ̶õ À©µµ¿ì¿¡¼­ ¼öÇàµÇ´ø ÇÁ·Î½ÃÁ®¸¦ »ç¿ëÀÚ Á¤ÀÇ ÇÁ·Î½ÃÁ®·Î ¿¬°áÇÏ¿© ¿øÇÏ´Â ÀÛ¾÷À» ÇÏ´Ù°¡ ±× ÀÛ¾÷ÀÌ ¿Ï·áµÇ¸é ´Ù½Ã ¿ø·¡ÀÇ ÇÁ·Î½ÃÁ®·Î µÇµ¹¾Æ¿À´Â ±â´ÉÀ» ¸»ÇÑ´Ù.

ÀÌ ¿¹Á¦¿¡¼­´Â ¼­ºêŬ·¡½ÌÀ» ÀÌ¿ëÇÏ¿© »ç¿ëÀÚ°¡ ¸®ÅÏ Å°¸¦ ÀÔ·ÂÇÑ »ç½ÇÀ» Parent À©µµ¿ì¿¡ ¾Ë·ÁÁØ´Ù. ¾Æ·¡ÀÇ ÇÁ·Î±×·¥ ÄÚµå´Â ÇöÀçÀÇ ÇÁ·Î½ÃÁ®¸¦ OldProc·Î Àá½Ã ÀúÀåÇÏ°í »ç¿ëÀÚ ÇÁ·Î½ÃÁ®ÀÎ EditProc¸¦ µî·ÏÇÏ´Â °ÍÀ» ³ªÅ¸³½´Ù.

OldProc = (WNDPROC) SetWindowLong (GetDlgItem(hWnd, IDC_EDIT),

GWL_WNDPROC, (LONG)EditProc);

À§¿¡¼­ IDC_EDIT´Â ¿¡µðÆ® ÄÁÆ®·ÑÀÇ IDÀ̸ç, EditProc´Â ¿¡µðÆ® ÄÁÆ®·ÑÀ» ó¸®Çϱâ À§ÇØ »õ·Î Á¤ÀÇÇÑ ÇÁ·Î½ÃÁ® À̸§ÀÌ´Ù.

 

          5-1-4. WM_CHAR ¸Þ½ÃÁö ó¸®

¾Æ·¡´Â EditProcÀÇ ±¸Çö ³»¿ëÀ¸·Î, »ç¿ëÀÚ°¡ Å°º¸µå·Î ±ÛÀÚ¸¦ ÀÔ·ÂÇÏ¿´À» ¶§ ¹ß»ýÇÏ´Â ¸Þ½ÃÁö WM_CHAR¸¦ ó¸®ÇÑ´Ù. ¸®ÅÏ Å°¸¦ Á¦¿ÜÇÑ ´Ù¸¥ ¹®ÀÚµéÀº ¸ðµÎ ¿ø·¡ÀÇ ÇÁ·Î½ÃÁ®·Î º¸

³»¸ç(CallWindowProc() È£Ãâ) »ç¿ëÀÚ°¡ ¸®ÅÏ Å°¸¦ ´©¸£¸é Áö±Ý±îÁö ¿¡µðÆ® ÄÁÆ®·Ñ¿¡ ÀúÀåµÈ µ¥ÀÌÅ͸¦ GetWindowText() ÇÔ¼ö¸¦ »ç¿ëÇÏ¿© ¾ò¾î¿Â ÈÄ PostMessage()¸¦ »ç¿ëÇÏ¿© »ç¿ëÀÚ Á¤ÀÇ ¸Þ½ÃÁö WM_ASYNC¸¦ ¹ß»ý½ÃŲ´Ù.

 

LRESULT CALLBACK EditProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {

switch(iMsg) {

case WM_CHAR:

if(wParam == VK_RETURN) { /* ¸®ÅÏÅ° ÀÔ·Â */

/* ÇöÀç ¿¡µðÆ® ÄÁÆ®·Ñ¿¡ ÀúÀåµÈ ¹®ÀÚ¿­À» ¾ò´Â´Ù */

GetWindowText(hWnd, (LPTSTR)msg, sizeof(msg));

/* WM_ASYNC ¸Þ½ÃÁö ¹ß»ý */

PostMessage(hParent, WM_ASYNC, m_s,

WSAMAKESELECTREPLY(FD_WRITE, 0));

SetWindowText(hWnd, "");

break;

}

}

/* ¸®ÅÏ Å°°¡ ¾Æ´Ï¸é ¿ø·¡ÀÇ ÇÁ·Î½ÃÁ®·Î ¹®ÀÚ¿­À» ÀÔ·Â */

return CallWindowProc(OldProc, hWnd, iMsg, wParam, lParam);

}

 

           5-1-5. WM_COMMANDÀÇ Ã³¸®

"Á¾·á" ¹öÆ°ÀÌ ´­¸± ¶§ ¹ß»ýÇÏ´Â ¸Þ½ÃÁö·Î ¼ÒÄÏÀ» Á¾·áÇϱâ À§ÇÏ¿© WSACleanup()À» È£ÃâÇÏ°í À©µµ¿ì¿¡ Á¾·á ¸Þ½ÃÁö WM_DESTROY¸¦ º¸³»±â À§ÇÏ¿© DestroyWindow() ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.

 

case WM_COMMAND:

switch(wParam) {

case IDC_EXIT: /* Á¾·á¹öÆ° ÀԷ ó¸® */

closesocket(m_s);

m_s = INVALID_SOCKET; /* ¼ÒÄÏÀ» ¿ø»óÅ·ΠÃʱâÈ­ */

WSACleanup();

DestroyWindow(hWnd); /* WM_DESTROY ¹ß»ý */

return TRUE;

}

break;

 

           5-1-6. WM_DESTROYÀÇ Ã³¸®

À§ÀÇ DestroyWindow()¿¡ ÀÇÇØ À©µµ¿ì ³»ºÎÀûÀ¸·Î ¹ß»ýÇÏ´Â ¸Þ½ÃÁö·Î¼­ À©µµ¿ì¸¦ Á¾·á½Ãų ¶§ »ç¿ëµÈ´Ù. ¾Æ·¡¿¡¼­ PostQuitMessage() ÇÔ¼ö´Â À©µµ¿ì ¸Þ½ÃÁö Å¥¿¡ Á¾·á ¸Þ½ÃÁö¸¦ Àü¼ÛÇÑ´Ù.

 

case WM_DESTROY:

PostQuitMessage(0);

return TRUE;

 

          5-1-7. WM_ASYNCÀÇ Ã³¸®

¼­¹ö¿ÍÀÇ ¿¬°á, ¿¬°áÁ¾·á, µ¥ÀÌÅÍ ¼Û¼ö½Å µîÀº ½Ã½ºÅÛÀÇ I/O º¯È­½Ã ¹ß»ýÇÏ´Â ¸Þ½ÃÁö WM_ASYNC¸¦ ÀÌ¿ëÇÏ¿© 󸮵ȴÙ. ¹ß»ýÇÑ À̺¥Æ®ÀÇ Á¾·ù¸¦ ±¸ºÐÇϱâ À§ÇÏ¿© ¸ÅÅ©·Î WSA- GETSELECTEVENT()¸¦ »ç¿ëÇÑ´Ù.

WChat_Client.c¿¡¼­ ó¸®ÇØ¾ß ÇÒ À̺¥Æ®ÀÇ Á¾·ù´Â FD_ CONNECT, FD_CLOSE, FD_WRITE, FD_READÀ̸ç À̵éÀ» °¢°¢ ó¸®ÇÏ´Â °ÍÀ» ¾Æ·¡¿¡ º¸¿´´Ù.

 

case WM_ASYNC:

hListBox = GetDlgItem(hWnd, IDC_LIST);

switch(WSAGETSELECTEVENT(lParam)) {

case FD_CONNECT:

/* ¼­¹ö¿Í ¿¬°á ó¸® */

case FD_CLOSE:

/* ¼ÒÄÏ Á¾·á ó¸® */

case FD_WRITE:

/* äÆà µ¥ÀÌÅÍ ¼Û½Å ó¸® */

case FD_READ:

/* äÆà µ¥ÀÌÅÍ ¼ö½Å ó¸® */

default:

break;

}

ÀÌ»óÀÌ WChat_Client.c ÇÁ·Î±×·¥ÀÌ´Ù.

 


 

6. À©¼ÓÀ» ÀÌ¿ëÇÑ Ã¤Æà ÇÁ·Î±×·¥(Use MFC in a Shared DLL)

      6-1. Server

 

     6-2. Client


 

 

 

 

 

 

 

 











 

 

 

 

          6-3. Server¿Í Client ¼Ò½º     ->     º°Ã· ÀÚ·á Âü°í.


 

7. Case ¿¬±¸

      7-6. Blocking Operation¿¡ ´ëÇÏ¿© ¾Ë¾Æº¸ÀÚ(TCP)

1) send(), recv()´Â ¾î¶² ¸ðµå·Î µ¿ÀÛÇϴ°¡?

 

¨ç µ¿ÀÛ ¼³¸í

send()°¡ ¾î¶² ¸ðµåÀÎÁö È®ÀÎÇϱâ À§Çؼ­´Â client°¡ data¸¦ º¸³»°í server°¡ data¸¦ ¹ÞÁö ¾Ê°í ´ë±âÇÏ°í ÀÖÀ» ¶§ clientÀÇ »óŸ¦ ÆľÇÇÑ´Ù. recv()´Â ±âº»¿¹Á¦·Î »ìÆ캸ÀÚ.

/*******************************************************************************/

/* ChatServer.cpp (winsocket ±âº»¿¹Á¦ Not Using MFC) */

/* case 7-6) send´Â ¾î¶² ¸ðµåÀΰ¡.? */

/* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.04.2 */

/*******************************************************************************/

#include <winsock2.h>

#include <iostream.h>

#define MAXLINE 512

#define DEFAULT_BUFFER 4096

DWORD WINAPI ClientThread(LPVOID lpParam)

{

SOCKET sock = (SOCKET)lpParam;

char szBuff[DEFAULT_BUFFER];

char *sMessage = "Server : Success Connecting";

int ret, senddata, num;

 

cout << "[Server] : Waiting for client data" << endl;

 

cout << "If continue, enter any number." << endl; // Updata send() mode Test

cin >> num; // Updata send() mode Test

ret = recv (sock, szBuff, DEFAULT_BUFFER, 0);

 

if(ret == SOCKET_ERROR)

{

cout << "Thread Socket : Recv() failed : " << WSAGetLastError() << endl;

return 0;

}

szBuff[ret] = '\0';

 

cout << "[Server] Data from Client : " << szBuff << endl;

senddata = send (sock, sMessage, strlen(sMessage), 0);

if(senddata == SOCKET_ERROR)

{

cout << "Thread Socket : Send() failed : "<< WSAGetLastError() << endl;

return 0;

}

cout << "[Server] Send response message to client" << endl;

cout << "Exit" << endl;

return 0;

}

int main ()

{

WSADATA wsd;

SOCKET Rsock;

SOCKET Csock;

HANDLE hThread;

DWORD dwThreadId;

int iAddrSize;

struct sockaddr_in local; //Server socket address struct

struct sockaddr_in client; //Client socket address struct

//winsock library initialize

if(WSAStartup(MAKEWORD(2,2), &wsd) != 0)

{

cout << "[Server] : Failed to load winsock library" << endl;

return -1;

}

else cout << "[Server] : Server WSAStartup"<< endl;

 

//listen socket create

Rsock = socket(AF_INET, SOCK_STREAM, 0);

if(Csock == SOCKET_ERROR)

{

cout << "[Server] : Socket create fail : " << WSAGetLastError();

return -1;

}

else cout << "[Server] : Socket Created" << endl;

 

//sockaddr_in description

local.sin_family = AF_INET;

local.sin_addr.s_addr = htonl(INADDR_ANY);

local.sin_port = htons(8198);

if(bind (Rsock, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)

{

cout << "[Server] : Bind fail : " << WSAGetLastError();

return -1;

}

cout << "[Server] : Socket Bind" << endl;

listen (Rsock, 8);

cout << "[Server] : Socket Listen" << endl;

cout << "[Server] : Waiting for connection request"<< endl;

while(1)

{

iAddrSize = sizeof(client);

Csock = accept (Rsock, (struct sockaddr *)&client, &iAddrSize);

cout << "[Server] : Client and Server connected : " <<

inet_ntoa(client.sin_addr) << " : " << ntohs(client.sin_port) << endl;

 

if (Csock == INVALID_SOCKET)

{

cout << "[Server] : Accept fail : " << WSAGetLastError();

break;

}

cout << "[Server] : Thread created" << endl;

hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)Csock, 0,

&dwThreadId);

 

if(hThread == NULL)

{

cout << "[Server] : CreateThread() failed : " << GetLastError() << endl;

break;

}

CloseHandle(hThread);

}

closesocket(Csock);

cout << "[Server] : Close Csock" << endl;

closesocket(Rsock);

cout << "[Server] : Close Rsock" << endl;

WSACleanup();

cout << "[Server] : WSACleanup" << endl;

return 0;

}

¨è ½ÇÇà °á°ú

server : server¸¦ ½ÇÇà½ÃÅ°°í ÀÓÀÇÀÇ ¼ö¸¦ ÀԷ¹ÞÀ» ¶§±îÁö ´ë±âÇÑ´Ù.

client : data¸¦ º¸³»°í ´ÙÀ½ ¸í·É¹®À» ½ÇÇàÇÏ¿´´Ù. À̷νá nonblockingÀÓÀ» È®ÀÎÇÑ´Ù.

¨é °á°ú ºÐ¼®

send()´Â nonblocking mode·Î µ¿ÀÛÇÑ´Ù. client¿¡¼­ data¸¦ º¸³»°í server¿¡¼­ recv()°¡ ¼öÇà°ú »ó°ü¾øÀÌ ´ÙÀ½ ¸í·É¹®À¸·Î ³Ñ¾î°£´Ù. recv()´Â blocking mode·Î µ¿ÀÛÇÑ´Ù. ±âº»¿¹Á¦ ¼öÇà °á°ú¸¦ º¸°í ¾Ë ¼ö Àִµ¥ server¿Í client°¡ Á¢¼ÓÀÌ ÀÌ·ç¾îÁø »óÅ¿¡¼­ server´Â client·ÎºÎÅÍ data¸¦ Àü´Þ¹ÞÀ» ¶§±îÁö block »óÅ·Π´ë±âÇÑ´Ù.

Âü°í) send´Â default·Î blocking ¸ðµå·Î ¼³Á¤µÇ¾îÀÖ´Ù.

2) accept¿Í connect´Â ¾î¶² mode·Î µ¿ÀÛÇϴ°¡?

¨ç µ¿ÀÛ ¼³¸í

accept°¡ ¾î¶² ¸ðµåÀÎÁö´Â ±âº»¿¹Á¦¿¡¼­ È®ÀÎ ÇÒ ¼ö ÀÖ´Ù. connect°¡ ¾î¶² ¸ðµåÀÎÁö¸¦ ¾Ë±â À§Çؼ­´Â client°¡ connect request¸¦ server¿¡°Ô º¸³ÂÀ» ¶§ server°¡ connect request¸¦ ¹ÞÁö ¾ÊÀ» ¶§¸¦ È®ÀÎÇÏ¸é ¾Ë ¼ö ÀÖ´Ù.