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 ÇÔ¼öµéÀ» Á¤¸®ÇÏ¿´´Ù.
Ç¥ 5-1 ´ëÇ¥ÀûÀÎ blocking ÇÔ¼ö Ç¥ 5-1¿¡ ¼Ò°³ÇÑ blocking ÇÔ¼öµéÀº ¼ÒÄÏÀÇ µ¿ÀÛ ¸ðµå¿¡ °ü°è¾øÀÌ Ç×»ó ºí·Ï µÉ ¼ö ÀÖ´Â ÇÔ¼öÀÌ´Ù. ÀÌ·¯ÇÑ ÇÔ¼ö¸¦ »ç¿ëÇÒ ¶§ ÇÁ·Î±×·¥ÀÌ ºí·Ï µÇ´Â ¹®Á¦¸¦ ÇØ°áÇϱâ À§ÇÏ¿©, À©¼Ó¿¡¼´Â À̵é blocking ÇÔ¼ö¿Í °°Àº ±â´ÉÀ» ¼öÇàÇÏ¸é¼ ½ÇÁ¦·Î´Â ºñµ¿±â ¸ðµå·Î µ¿ÀÛÇÏ´Â Áï, ÇÔ¼ö ½ÇÇà°á°ú¸¦ ºñµ¿±âÀûÀ¸·Î ¾Ë·ÁÁÖ´Â ºñµ¿±â ÇÔ¼öµéÀ» Á¦°øÇÏ°í ÀÖ´Ù.
Ç¥ 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()À» È£ÃâÇÏ´Â ¿¹ÀÌ´Ù.
À§¿¡¼ wsaData´Â WSADATA ŸÀÔÀÇ ±¸Á¶Ã¼ º¯¼ö·Î ¿©±â¿¡´Â WSAStartup() ÇÔ¼ö°¡ °³¼³ÇÏ¿© ¾ÕÀ¸·Î »ç¿ëÇÒ À©¼Ó¿¡ °üÇÑ Á¤º¸°¡ ¼ö·ÏµÇ¾î ¸®ÅÏ µÈ´Ù.
WSADATA ±¸Á¶Ã¼ÀÇ Á¤ÀÇ´Â ´ÙÀ½°ú °°´Ù(Winsock.h ÆÄÀÏ ÂüÁ¶).
1-3-2. WSACleanup()
À©¼ÓÀÇ »ç¿ëÀ» Á¾·áÇÒ ¶§ È£ÃâÇϸç WSAStartup()¿¡ ´ëÀÀµÇ´Â ÇÔ¼öÀÌ´Ù.
2. À©¼ÓÀÇ µ¿ÀÛ
À©¼Ó °ü·Ã ÇÔ¼öµéÀÇ »ç¿ë¹ý Áï, ÇÔ¼öÈ£Ãâ ¼ø¼¿Í ÇÔ¼öÀÇ ÀÎÀÚ ¹× °á°ú ¸®ÅÏ °ª µîÀº BSD ¼ÒÄÏÀÇ »ç¿ë¹ý°ú °ÅÀÇ °°´Ù.
2-1. ±âº»ÀûÀÎ À©¼Ó ÇÔ¼ö
2-1-1. socket()
À©¼Ó¿¡¼µµ BSD ¼ÒÄÏ ÇÁ·Î±×·¥¿¡¼¿Í °°ÀÌ socket() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© Åë½ÅÀÇ Ã¢±¸ ¿ªÇÒÀ» ÇÏ´Â ¼ÒÄÏÀ» »ý¼ºÇÑ´Ù. ¾Æ·¡´Â socket()ÀÇ »ç¿ë ¿¹·Î ÀÎÅÍ³Ý µµ¸ÞÀÎÀÇ ÁÖ¼Ò Ã¼°è¿¡¼ ½ºÆ®¸²Çü ¼ÒÄÏÀ» °³¼³ÇÏ´Â °ÍÀ» º¸¿´´Ù.
socket() ÇÔ¼öÀÇ Ã¹ ¹ø° ÀÎÀÚ´Â ¼ÒÄÏÀÌ »ç¿ëÇÒ ÁÖ¼Ò Ã¼°è(Address Family)ÀÇ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù. À©¼Ó ¹öÀü 1.1¿¡¼´Â ÀÎÅÍ³Ý ÁÖ¼Òü°è(AF_INET)¸¸À» Áö¿øÇÑ´Ù. µÎ ¹ø° ÀÎÀÚ´Â Æ®·£½ºÆ÷Æ® ÇÁ·ÎÅäÄÝÀ» ÁöÁ¤Çϴµ¥ ¿¬°áÇüÀÎ ½ºÆ®¸² ¼ÒÄÏÀ» °³¼³ÇÏ·Á¸é SOCK_STREAMÀ», ºñ¿¬°áÇüÀÎ µ¥ÀÌÅͱ׷¥ ÇüÅÂÀÇ ¼ÒÄÏÀ» °³¼³ÇÏ·Á¸é SOCK_ DGRAMÀ» ¼±ÅÃÇÑ´Ù. ¼¼ ¹ø° ÀÎÀÚ´Â ÇÁ·ÎÅäÄÝ Å¸ÀÔ(Type)Àε¥ ÀϹÝÀûÀ¸·Î 0À» ¾´´Ù.
socket()ÀÇ ¼öÇàÀÌ ¼º°øÇÑ °æ¿ì¿¡´Â »õ·Î¿î ¼ÒÄϹøÈ£¸¦ ¸®ÅÏÇÏ°í, ½ÇÆÐÇÑ °æ¿ì¿¡´Â INVALID_SOCKETÀÌ ¸®ÅÏ µÈ´Ù. À§¿¡¼ WSAGetLastError()´Â °¡Àå ÃÖ±Ù¿¡ ¹ß»ýÇÑ À©¼Ó °ü·Ã ÇÔ¼öÀÇ ¿¡·¯Äڵ带 ¸®ÅÏ ÇÏ´Â ÇÔ¼öÀÌ´Ù. MessageBox()´Â ¸Þ½ÃÁö »óÀÚ¸¦ ¸¸µé¾î ȸ鿡 Ãâ·ÂÇÏ´Â À©µµ¿ì ÇÔ¼öÀÌ´Ù. MessageBox()ÀÇ ¿øÇüÀº ´ÙÀ½°ú °°À¸¸ç À§¿¡¼´Â ¿¡·¯ ¸Þ½ÃÁö¿Í OK ¹öÆ°À» Ãâ·ÂÇÏ°í ÀÖ´Ù.
À§¿¡¼ 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À» º¸¿©ÁÖ°í ÀÖ´Ù.
¾Æ·¡ ÇÁ·Î±×·¥ ÄÚµå´Â bind() ÇÔ¼öÀÇ »ç¿ë ¿¹Àε¥ Æ÷Æ®¹øÈ£·Î 3000¹øÀ» ÁöÁ¤ÇÏ°í ÀÖ´Ù.
À§¿¡¼ 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¿¡ ½Ç·ÁÀÖ°Ô µÈ´Ù.
2-1-5. connect()
¿¬°áÇü ¼ÒÄÏÀ» °³¼³ÇÑ Å¬¶óÀ̾ðÆ®°¡ ¼¹ö¿Í Åë½ÅÀ» ÇÏ·Á¸é ¸ÕÀú ¼¹ö¿Í ¿¬°áµÇ¾î¾ß Çϴµ¥ À̸¦ À§ÇÏ¿© Ŭ¶óÀ̾ðÆ®°¡ È£ÃâÇÏ´Â ÇÔ¼ö°¡ connect()ÀÌ´Ù. ÀÌ·¯ÇÑ Å¬¶óÀ̾ðÆ®ÀÇ connect() È£Ãâ¿¡ ´ëÇØ, ¼¹ö°¡ ¹Ì¸® È£ÃâÇØ µÐ accept()°¡ Á¤»óÀûÀ¸·Î ó¸®µÇ¾î ¿¬°áÀÌ ¿Ï·áµÇ¸é connect()´Â 0À» ¸®ÅÏ ÇÑ´Ù.
´ÙÀ½Àº connect()ÀÇ »ç¿ë ¿¹ÀÌ´Ù.
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ÀÇ ÁÖ¼Ò¸¦ °¡¸®Å°µµ·Ï ÇÑ´Ù.
¿¹¸¦ µé¾î ¹Ì ó¸®µÈ ÆÐŶµéÀ» ¹Ù·Î ¹ö¸®Áö ¾Ê°í ÁöÁ¤µÈ ½Ã°£ ³»¿¡ 󸮵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()ÀÇ »ç¿ë ¹®¹ýÀÌ´Ù.
WSAAsyncSelect()´Â È£Ãâ Áï½Ã ¸®ÅÏ µÇ¸ç ¿¡·¯¹ß»ý ½Ã¿¡´Â SOCKET_ERROR¸¦ ¸®ÅÏ ÇÑ´Ù. ¿¡·¯°¡ ¹ß»ýÇÏ´Â °æ¿ì´Â Winsock.dllÀÌ ÃʱâȵÇÁö ¾Ê¾Ò°Å³ª, ³×Æ®¿÷ÀÌ µ¿ÀÛÇÏÁö ¾Ê°Å³ª, ´Ù¸¥ blocking ÇÔ¼ö°¡ ó¸®ÁßÀ̰ųª, ÇÔ¼öÀÇ ÀÎÀÚ¸¦ À߸ø ÀÔ·ÂÇÑ °æ¿ìÀÌ´Ù. WSAAsyncSelect()°¡ ¿¡·¯ ¾øÀÌ ¸®ÅÏ µÇ¸é ´ÙÀ½°ú °°Àº Á¶°ÇÀÌ ¸¸Á·µÈ °ÍÀÌ´Ù.
1) ¼ÒÄÏÀÌ ºñµ¿±â ¸ðµå·Î µÇ¾ú´Ù. 2) ¿øÇÏ´Â À̺¥Æ®°¡ ¹ß»ýÇÏ¸é ±× »ç½ÇÀÌ ¸Þ½ÃÁö·Î Àü´ÞµÉ °ÍÀÌ´Ù. 3) ÀÌ ¼ÒÄÏ¿¡ accept()°¡ È£ÃâµÇ¾î »õ·Î¿î ¼ÒÄÏÀÌ ¸¸µé¾îÁö¸é »õ·Î¿î ¼ÒÄÏ¿¡ ´ëÇؼµµ WSAAsyncSelect() È£Ã⠽à ¿ä±¸ÇÑ À̺¥Æ®¸¦ ¶È°°ÀÌ Ã³¸®ÇØ ÁØ´Ù. WSAAsyncSelect()¸¦ È£ÃâÇÏ¸é ¼ÒÄÏÀº ºñµ¿±â ¸ðµå·Î ¹Ù²î°í ¼ÒÄÏ¿¡¼ ÁöÁ¤µÈ À̺¥Æ®°¡ ¹ß»ýÇÏ¸é ¸Þ½ÃÁö Àü´ÞÀ» ÅëÇÏ¿© ÀÌ »ç½ÇÀ» WSAAsyncSelect()¸¦ È£ÃâÇÑ ÀÀ¿ë ÇÁ·Î±×·¥¿¡°Ô ¾Ë¸®°Ô µÈ´Ù. ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼´Â °¢ À̺¥Æ®¿¡ ÇØ´çÇÏ´Â ±â´ÉÀ» ¼öÇàÇÏ¸é µÈ´Ù. À̺¥Æ®ÀÇ Á¾·ù¿¡´Â ¼ö½Å µ¥ÀÌÅÍÀÇ µµÂø, µ¥ÀÌÅ͸¦ ¼Û½ÅÇÒ Áغñ°¡ µÊ, ¿¬°á¿äûÀ» acceptÇÒ Áغñ°¡ µÊ µîÀÇ »ç°ÇµéÀÌ Àִµ¥, ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ °ü½ÉÀ» °®´Â À̺¥Æ® Áï, ¾Ë°í ½ÍÀº ¼ÒÄÏÀÇ »óź¯È´Â WSAAsyncSelect()¸¦ È£ÃâÇÒ ¶§ Event ÀÎÀÚ¿¡ ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. ÇØ´ç ¼ÒÄÏ¿¡¼, Event ÀÎÀÚ¿¡ ÁöÁ¤µÈ À̺¥Æ® Áß Çϳª¶óµµ ¹ß»ýÇϸé À©¼ÓÀº ÀÀ¿ë ÇÁ·Î±×·¥¿¡°Ô ÀÌ »ç½ÇÀ» ¾Ë·ÁÁÖ°Ô µÈ´Ù. À̺¥Æ®ÀÇ Á¾·ù´Â Ç¥ 5-3°ú °°´Ù.
Ç¥ 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)¸¦ º¸³»µµ·Ï ÇÏ´Â ¿¹ÀÌ´Ù.
À̺¥Æ®¸¦ ó¸®ÇÏ´Â ÇÁ·Î±×·¥¿¡¼´Â À̺¥Æ®ÀÇ Á¾·ù¸¦ ¾Ë±â À§ÇÏ¿© º¯¼ö lParam¸¦ ÂüÁ¶ÇÏ¿©¾ß Çϴµ¥ lParamÀÇ ÇÏÀ§ 16ºñÆ®¿¡´Â ¹ß»ýÇÑ À̺¥Æ®ÀÇ Á¾·ù°¡ ½Ç·ÁÀÖ°í »óÀ§ 16ºñÆ®¿¡´Â ¿¡·¯Äڵ尡 ½Ç·ÁÀÖ´Ù. ÀÌ·¯ÇÑ À̺¥Æ® Á¾·ù¿Í ¿¡·¯Äڵ带 lParam¿¡¼ Æí¸®ÇÏ°Ô Ã£¾Æ³»±â À§ÇÏ¿© ¸ÅÅ©·Î WSAGETSELECTEVENT()¿Í WSA- GETSELECTERROR()°¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ´Ù.
¾Æ·¡ÀÇ ÄÚµå´Â ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼ ¹ß»ýÇÑ À̺¥Æ®°¡ FD_ACCEPTÀÎÁö¸¦ Áï, Ŭ¶óÀ̾ðÆ®·ÎºÎÅÍ ¿¬°á¿äûÀÌ ¿Í¼ À̺¥Æ®°¡ ¹ß»ýÇß´ÂÁö¸¦ È®ÀÎÇÏ°í accept()¸¦ È£ÃâÇÏ´Â ¿¹ÀÌ´Ù.
¾î¶² ¼ÒÄÏ¿¡¼ À̺¥Æ®°¡ Çϳª ¹ß»ýÇÏ¸é ¸Þ½ÃÁö Àü¼ÛÀº Çѹø¸¸ ÀϾÙ. ±×·¯³ª ÀÌ ¼ÒÄÏ¿¡ °°Àº Á¾·ùÀÇ À̺¥Æ®°¡ ´Ù½Ã ¹ß»ýÇÒ ¼ö Àִµ¥, ÀÌ¿Í °°ÀÌ °°Àº À̺¥Æ®°¡ ´Ù½Ã ¹ß»ýÇÒ ¶§¸¶´Ù »õ·Î¿î ¸Þ½ÃÁö°¡ ÀÀ¿ë ÇÁ·Î±×·¥À¸·Î Àü´ÞµÇµµ·Ï ÇÏ´Â °ÍÀÌ ÇÊ¿äÇÏ´Ù. ¿¹¸¦ µé¾î FD_READ À̺¥Æ®°¡ ¹ß»ýÇÑ ¼ÒÄÏ¿¡ ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ recv() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© µ¥ÀÌÅ͸¦ ÀоîµéÀÎ ÈÄ¿¡ »õ·Î¿î µ¥ÀÌÅÍ°¡ ¼ö½ÅµÇ¸é FD_READ À̺¥Æ®°¡ ´Ù½Ã ¹ß»ýÇÏ¿©¾ß À̸¦ ÀÐÀ» ¼ö ÀÖ´Ù. ÀÌ°ÍÀº recv() È£Ãâ½Ã ³»ºÎÀûÀ¸·Î ÀÚµ¿À¸·Î 󸮵ǵµ·Ï µÇ¾î ÀÖ´Ù(Áï, revc() È£ÃâÀÌ WASAsyncSelect()¸¦ ´Ù½Ã È£ÃâÇÑ È¿°ú¸¦ ÁØ´Ù). Ç¥ 5-4¿¡ °°Àº Á¾·ùÀÇ ¸Þ½ÃÁö¸¦ ¹Ýº¹ÇÏ¿© ¹ß»ý½ÃÅ°µµ·Ï ÇÏ´Â ÇÔ¼öµé°ú ÇØ´ç À̺¥Æ®¸¦ Á¤¸®ÇÏ¿´´Ù. ¿¹¸¦ µé¾î FD_ACCEPT À̺¥Æ®°¡ ¹ß»ýÇÏ¿´À» ¶§ accept()¸¦ È£ÃâÇÏ¿© À̸¦ ó¸®ÇÏ¸é »õ·Î¿î FD_ACCEPT°¡ ¹ß»ýÇÒ ¶§ °°Àº Á¾·ùÀÇ ¸Þ½ÃÁö°¡ ´Ù½Ã ÀÀ¿ë ÇÁ·Î±×·¥¿¡°Ô Àü´ÞµÈ´Ù.
Ç¥ 5-4 ¸Þ½ÃÁö ¹Ýº¹ ¹ß»ý ÇÔ¼ö
2-3. À©¼ÓÀÇ IP ÁÖ¼Ò º¯È¯ ÇÔ¼ö
2-3-1. WSAAsyncGetHostByAddr()
IP ÁּҷκÎÅÍ ÇØ´ç È£½ºÆ®ÀÇ À̸§°ú ±âŸ Á¤º¸¸¦ ¾Ë¾Æ³»±â À§ÇÑ ºñµ¿±â ÇÔ¼öÀ̸ç BSD ¼ÒÄÏÀÇ gethostbyaddr()°ú ¸¶Âù°¡Áö·Î hostent ±¸Á¶Ã¼¸¦ ¸®ÅÏ ÇÑ´Ù. hostent ±¸Á¶Ã¼ÀÇ ³»¿ëÀº ¾Æ·¡¿Í °°´Ù.
WSAAsyncGetHostByAddr()ÀÇ »ç¿ë ¹®¹ýÀº ´ÙÀ½°ú °°´Ù.
¾Æ·¡´Â WSAAsyncGetHostByAddr()ÀÇ »ç¿ë ¿¹Àε¥ IP ÁÖ¼Ò°¡ 203.252.65.3ÀΠȣ½ºÆ®ÀÇ µµ¸ÞÀÎ ³×ÀÓÀ» ¸Þ½ÃÁö ¹Ú½º¿¡ Ãâ·ÂÇÑ´Ù. ¾Æ·¡¿¡¼ PHOSTENT´Â hostent ±¸Á¶Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ Å¸ÀÔÀ» ÁöÁ¤Çϸç MAXGETHOSTSTRUCT´Â hostent ±¸Á¶Ã¼¸¦ ´ã±â¿¡ ÃæºÐÇÑ Å©±âÀÇ »ó¼ö·Î Winsock.h¿¡ Á¤ÀǵǾî ÀÖ´Ù.
ÇÑÆí WSAAsyncGetXByY°ú °°Àº ÇüÅÂÀÇ ºñµ¿±â ÇÔ¼öÀÇ ½ÇÇà °á°ú´Â lParam¿¡ µé¾îÀÖ°Ô µÈ´Ù. lParamÀÇ »óÀ§ 16ºñÆ®¿¡´Â ¿¡·¯Äڵ尡 ÇÏÀ§ 16ºñÆ®¿¡´Â ºñµ¿±â ÇÔ¼ö ½ÇÇà °á°ú°¡ µé¾îÀÖ´Â ¹öÆÛÀÇ Å©±â°¡ µé¾î ÀÖ´Ù. ÀÌ·¯ÇÑ ¿¡·¯ °ª°ú ¹öÆÛÀÇ Å©±â °ªÀ» lParamÀ¸·ÎºÎÅÍ Æí¸®ÇÏ°Ô ¾Ë¾Æ³»±â À§ÇÏ¿© WSAGETASYNCERROR()¿Í WSAGETASYNCBUFLEN() ¸ÅÅ©·Î°¡ °¢°¢ Á¤ÀǵǾî ÀÖ´Ù.
2-3-2. WSAAsyncGetServByName()
ÀÌ ÇÔ¼ö´Â ftp, mail°ú °°Àº TCP/IP Ç¥ÁØ ÀÀ¿ë ÇÁ·Î±×·¥ÀÇ Æ÷Æ®¹øÈ£¸¦ ã±â À§ÇØ »ç¿ëµÇ´Â ºñµ¿±â ÇÔ¼öÀÌ´Ù.
ÀÌ ÇÔ¼ö°¡ ¼º°øÀûÀ¸·Î ¼öÇàµÇ¸é servent¶ó´Â ±¸Á¶Ã¼ÀÇ Æ÷ÀÎÅ͸¦ ¸®ÅÏÇϴµ¥ servent ±¸Á¶Ã¼ÀÇ ³»¿ëÀº ´ÙÀ½°ú °°´Ù.
WSAAsyncGetServByName()ÀÇ »ç¿ë ¹®¹ýÀº ´ÙÀ½°ú °°´Ù.
ÀÌ ÇÔ¼öÀÇ »ç¿ë ¿¹·Î UDP ÇÁ·ÎÅäÄÝ·Î ±¸ÇöµÈ time ¼ºñ½ºÀÇ Æ÷Æ®¹øÈ£¸¦ ã¾Æ³»¾î ȸ鿡 Ãâ·ÂÇÏ´Â ¿¹¸¦ ¾Æ·¡¿¡ º¸¿´´Ù. ¿©±â¼ PSERVENT´Â servent ±¸Á¶Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ Å¸ÀÔÀ» ¸»ÇÑ´Ù.
2-3-3. WSAAsyncGetHostByName()
ÀÌ ÇÔ¼ö´Â È£½ºÆ® À̸§À» »ç¿ëÇÏ¿© IP ÁÖ¼Ò¸¦ ã¾Æ³»´Â ÇÔ¼öÀÌ¸ç »ç¿ë ¹®¹ýÀº ¾Æ·¡¿Í °°´Ù.
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·Î ÀÛ¼ºÇÏ¿´´Ù.
4-1-2. Àü¿ª º¯¼ö
äÆà ¼¹ö ÇÁ·Î±×·¥¿¡¼ »ç¿ëÇÏ´Â Àü¿ª º¯¼ö¿Í °¢°¢ÀÇ ±â´ÉÀº ´ÙÀ½°ú °°´Ù.
4-1-3. WinMain() ÇÔ¼ö
º» ¿¹Á¦¿¡¼´Â À©µµ¿ì ´ëÈ»óÀÚ(DialogBox)¸¦ ¸ÞÀÎ À©µµ¿ì·Î »ç¿ëÇÏ°í ÀÖ´Ù. ¾Æ·¡ÀÇ ÄÚµå´Â WinMain() Áß¿¡¼ CreateDialog()·Î ´ëÈ»óÀÚ¸¦ »ý¼ºÇÏ°í, GetMessage()·Î ´ëÈ»óÀÚ¿¡ µµÂøÇÏ´Â ¸Þ½ÃÁö¸¦ ¹Þ¾Æ À̸¦ ó¸®ÇÏ´Â ·çÇÁ¸¦ º¸ÀÌ°í ÀÖ´Ù.
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ÀÇ Á¾·ù¿¡ µû¶ó ÇØ¾ß ÇÒ ÀÏÀ» ´ÙÀ½°ú °°ÀÌ ±¸ºÐÇÑ´Ù.
4-1-5. WM_INITDIALOGÀÇ Ã³¸®
WChat_Server.c¿¡¼´Â WM_INITDIALOG ¸Þ½ÃÁö°¡ ¹ß»ýÇÏ¸é »ç¿ëÀÚ Á¤ÀÇ ÇÔ¼öÀÎ InitSocket()À» È£ÃâÇϵµ·Ï ÇÏ¿´´Ù. InitSocket() ÇÔ¼ö¿¡¼´Â WSAStartup() ½Ã½ºÅÛ ÄÝÀ» È£ÃâÇÏ¿© Winsock.dllÀ» ÃʱâÈÇÑ´Ù. À©¼Ó¿¡¼µµ ¼ÒÄÏÀÇ »ý¼ºÀº BSD ¼ÒÄÏ¿¡¼¿Í °°ÀÌ socket() ÇÔ¼ö¸¦ ÅëÇؼ ÀÌ·ç¾îÁø´Ù ¾Æ·¡´Â ¼ÒÄÏÀ» ¸¸µé°í ¼ÒÄϹøÈ£(m_sAccept)¿Í ¼ÒÄÏÁÖ¼Ò ±¸Á¶Ã¼ serv_addr¸¦ bind()ÇÑ ÈÄ listen()À» È£ÃâÇÏ´Â °ÍÀ» º¸ÀÌ°í ÀÖ´Ù.
4-1-6. WM_COMMANDÀÇ Ã³¸®
WM_COMMAND ¸Þ½ÃÁö´Â »ç¿ëÀÚ°¡ ¹öÆ°, ¸®½ºÆ®¹Ú½º, üũ¹Ú½º, ¿¡µðÆ®¹Ú½º, ¸Þ´º µîÀ» »ç¿ëÇÒ ¶§ ¹ß»ýÇÏ´Â ¸Þ½ÃÁöÀÌ´Ù. ÀÌ ÇÁ·Î±×·¥¿¡¼´Â "Á¾·á" ¹öÆ°ÀÌ ´¸± ¶§ ¹ß»ýÇÏ´Â ¸Þ½ÃÁö¸¸ ó¸®ÇÏ¸é µÈ´Ù. ¾Æ·¡ÀÇ WM_COMMAND 󸮺κп¡¼ wParamÀº À§¿¡ ¿°ÅÇÑ °Í°ú °°Àº ¿©·¯ Á¾·ùÀÇ ¸Þ ½ÃÁö¸¦ ±¸ºÐÇÏ´Â ÆĶó¹ÌÅÍÀ̸ç IDC_EXIT´Â Á¾·á ¹öÆ°ÀÇ IDÀÌ´Ù. ÇÑÆí DestroyWindow() ÇÔ¼ö´Â À©µµ¿ì ³»ºÎ¿¡ WM_ DESTROY ¸Þ½ÃÁö¸¦ º¸³»ÁØ´Ù.
4-1-7. WM_DESTROYÀÇ Ã³¸®
WM_DESTROY´Â (À§ÀÇ DestroyWindow()¿¡ ÀÇÇØ) À©µµ¿ì¿¡¼ ³»ºÎÀûÀ¸·Î ¹ß»ýµÇ´Â ¸Þ½ÃÁö·Î À©µµ¿ì¸¦ Á¾·á½Ãų ¶§ »ç¿ëµÈ´Ù. ´ÙÀ½ÀÇ Äڵ忡¼ PostQuitMessage()´Â À©µµ¿ì ¸Þ½ÃÁö Å¥¿¡ Á¾·á ¸Þ½ÃÁö¸¦ Àü¼ÛÇÏ´Â ÇÔ¼öÀÌ´Ù.
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´Â Àü¼ÛÇÒ ¸Þ½ÃÁö¸¦ ³ªÅ¸³½´Ù.
2)¹øÀÇ °æ¿ì´Â »õ·Î¿î äÆà Ŭ¶óÀ̾ðÆ®°¡ Ãß°¡·Î ¿¬°áµÉ ¶§ Áï, accept()°¡ ¼º°øÀûÀ¸·Î ¼öÇàµÇ¾úÀ» ¶§ accept()°¡ ¸®ÅÏÇÑ ¼ÒÄϹøÈ£ m_sClient[m_Total]¿¡ ´ëÇÏ¿© ¼öÇàµÈ´Ù(m_TotalÀº ÇöÀç äÆÿ¡ Âü°¡ÇÑ ÃÑ »ç¶÷¼ö). ±×·¯³ª 2)ÀÇ °æ¿ì´Â 1)ÀÇ °æ¿ì¿Í ´Þ¸® °¢ Ŭ¶óÀ̾ðÆ®¿ÍÀÇ µ¥ÀÌÅÍÀÇ ¼Û½Å, ¼ö½Å, Á¾·á µî ¼¼ °¡Áö À̺¥Æ®¸¦ ó¸®ÇÏ¿©¾ß ÇϹǷΠFD_ACCEPT°¡ ¾Æ´Ï¶ó FD_READ|FD_WRITE| FD_CLOSE¸¦ À̺¥Æ® ¸®½ºÆ®·Î ÁöÁ¤ÇÏ¿©¾ß ÇÑ´Ù. ¾Æ·¡´Â ÀÌ·¯ÇÑ ±â´ÉÀ» ¼öÇàÇÏ´Â ÇÁ·Î±×·¥ ÄÚµåÀÌ¸ç ¿©±â¼ msg¿¡´Â ¸ðµç äÆà °¡ÀÔÀÚ¿¡°Ô º¸³»´Â ¸Þ½ÃÁö°¡ ÀúÀåµÈ´Ù.
WSAAsyncSelect()¸¦ È£ÃâÇØ µÐ ÀÌÈÄ¿¡ WM_ASYNC ¸Þ½ÃÁö°¡ ¹ß»ýÇÏ¸é ¾î´À ¼ÒÄÏ¿¡¼ ÀÌ ¸Þ½ÃÁö¸¦ ¹ß»ý½ÃÄ×´ÂÁö¸¦ ¾Ë¾Æ³»¾ß ÇÑ´Ù. ¾Æ·¡´Â ÀÌ·¯ÇÑ ±â´ÉÀ» ó¸®ÇÏ´Â ÇÁ·Î±×·¥ ÄÚµåÀε¥, WM_ ASYNC ¸Þ½ÃÁö¸¦ ¹ß»ý½ÃŲ ¼ÒÄÏÀÌ ¾î¶² ¼ÒÄÏÀÎÁö È®ÀÎÇϱâ À§ÇÏ¿© Àӽà ¼ÒÄϹøÈ£ sock_tmp¸¦ »ç¿ëÇÏ°í ÀÖ´Ù.
4-1-9. µ¥ÀÌÅÍ ¼Û¼ö½Å
WSAAsyncSelect()¿¡¼ ÁöÁ¤ÇÑ »ç¿ëÀÚ ¸Þ½ÃÁö WM_ASYNC°¡ ¹ß»ýÇÏ¿´À» ¶§ ¼ÒÄÏ¿¡¼ ¹ß»ýÇÑ À̺¥Æ®ÀÇ ±¸Ã¼ÀûÀÎ ³»¿ëÀÌ lParam ÆĶó¹ÌÅÍ¿¡ µé¾î ÀÖ°Ô µÈ´Ù. µû¶ó¼ lParamÀÇ °ªÀ» È®ÀÎÇÏ¿© µ¥ÀÌÅÍÀÇ ¼Û½Å ¹× ¼ö½Å µîÀÇ ÀûÀýÇÑ ±â´ÉÀ» ó¸®ÇÏ¸é µÈ´Ù. ´ÙÀ½¿¡ µ¥ÀÌÅÍ Àбâ, ¾²±â, Á¾·á À̺¥Æ®¸¦ °¢°¢ ó¸®ÇÏ´Â °ÍÀ» º¸ÀÌ°í ÀÖ´Ù.
ÀÌ»óÀÌ 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´Â ´ÙÀ½°ú °°Àº Çì´õ ÆÄÀÏ°ú Àü¿ªº¯¼ö¸¦ ÇÊ¿ä·Î ÇÑ´Ù.
5-1-2. WM_INITDIALOGÀÇ Ã³¸®
À©µµ¿ì°¡ óÀ½ »ý¼³ µÉ ¶§ ¹ß»ýÇÏ´Â ¸Þ½ÃÁöÀÎ WM_ INITDIALOGÀÇ Ã³¸®ºÎ¿¡¼´Â ´ÙÀ½°ú °°ÀÌ À©¼ÓÀÇ ÃʱâÈ(InitSocket())¿Í ´ÙÀ½¿¡ ¼³¸íÇÑ ¿¡µðÆ® ÄÁÆ®·Ñ ¼ºêŬ·¡½Ì(subclassing)À» ¼öÇàÇÑ´Ù.
5-1-3. ¼ºêŬ·¡½Ì
Ŭ¶óÀ̾ðÆ® ÇÁ·Î±×·¥Àº ´ÙÀ̾ó·Î±× ¹Ú½º·ÎºÎÅÍ ½ÇÇàÀÌ ½ÃÀ۵Ǵµ¥ ¿¡µðÆ® ÄÁÆ®·Ñ(edit control)À» ÅëÇÏ¿© µ¥ÀÌÅ͸¦ ÀԷ¹޴´Ù. ¿¡µðÆ® ÄÁÆ®·Ñ¿¡¼´Â »ç¿ëÀÚ°¡ ¸®ÅÏ('\n')±îÁö ÀÔ·ÂÇÑ ¹®ÀÚ¿À» ¹Þ¾Æ, »ç¿ëÀÚ Á¤ÀÇ ¸Þ½ÃÁöÀÎ WM_ASYNC¸¦ ÀÌ¿ëÇÏ¿© ó¸®ÇÑ´Ù. À̸¦ À§ÇÏ¿© ¼ºêŬ·¡½ÌÀ» »ç¿ëÇÑ´Ù. ¼ºêŬ·¡½ÌÀ̶õ À©µµ¿ì¿¡¼ ¼öÇàµÇ´ø ÇÁ·Î½ÃÁ®¸¦ »ç¿ëÀÚ Á¤ÀÇ ÇÁ·Î½ÃÁ®·Î ¿¬°áÇÏ¿© ¿øÇÏ´Â ÀÛ¾÷À» ÇÏ´Ù°¡ ±× ÀÛ¾÷ÀÌ ¿Ï·áµÇ¸é ´Ù½Ã ¿ø·¡ÀÇ ÇÁ·Î½ÃÁ®·Î µÇµ¹¾Æ¿À´Â ±â´ÉÀ» ¸»ÇÑ´Ù. ÀÌ ¿¹Á¦¿¡¼´Â ¼ºêŬ·¡½ÌÀ» ÀÌ¿ëÇÏ¿© »ç¿ëÀÚ°¡ ¸®ÅÏ Å°¸¦ ÀÔ·ÂÇÑ »ç½ÇÀ» Parent À©µµ¿ì¿¡ ¾Ë·ÁÁØ´Ù. ¾Æ·¡ÀÇ ÇÁ·Î±×·¥ ÄÚµå´Â ÇöÀçÀÇ ÇÁ·Î½ÃÁ®¸¦ OldProc·Î Àá½Ã ÀúÀåÇÏ°í »ç¿ëÀÚ ÇÁ·Î½ÃÁ®ÀÎ EditProc¸¦ µî·ÏÇÏ´Â °ÍÀ» ³ªÅ¸³½´Ù.
À§¿¡¼ IDC_EDIT´Â ¿¡µðÆ® ÄÁÆ®·ÑÀÇ IDÀ̸ç, EditProc´Â ¿¡µðÆ® ÄÁÆ®·ÑÀ» ó¸®Çϱâ À§ÇØ »õ·Î Á¤ÀÇÇÑ ÇÁ·Î½ÃÁ® À̸§ÀÌ´Ù.
5-1-4. WM_CHAR ¸Þ½ÃÁö ó¸®
¾Æ·¡´Â EditProcÀÇ ±¸Çö ³»¿ëÀ¸·Î, »ç¿ëÀÚ°¡ Å°º¸µå·Î ±ÛÀÚ¸¦ ÀÔ·ÂÇÏ¿´À» ¶§ ¹ß»ýÇÏ´Â ¸Þ½ÃÁö WM_CHAR¸¦ ó¸®ÇÑ´Ù. ¸®ÅÏ Å°¸¦ Á¦¿ÜÇÑ ´Ù¸¥ ¹®ÀÚµéÀº ¸ðµÎ ¿ø·¡ÀÇ ÇÁ·Î½ÃÁ®·Î º¸ ³»¸ç(CallWindowProc() È£Ãâ) »ç¿ëÀÚ°¡ ¸®ÅÏ Å°¸¦ ´©¸£¸é Áö±Ý±îÁö ¿¡µðÆ® ÄÁÆ®·Ñ¿¡ ÀúÀåµÈ µ¥ÀÌÅ͸¦ GetWindowText() ÇÔ¼ö¸¦ »ç¿ëÇÏ¿© ¾ò¾î¿Â ÈÄ PostMessage()¸¦ »ç¿ëÇÏ¿© »ç¿ëÀÚ Á¤ÀÇ ¸Þ½ÃÁö WM_ASYNC¸¦ ¹ß»ý½ÃŲ´Ù.
5-1-5. WM_COMMANDÀÇ Ã³¸®
"Á¾·á" ¹öÆ°ÀÌ ´¸± ¶§ ¹ß»ýÇÏ´Â ¸Þ½ÃÁö·Î ¼ÒÄÏÀ» Á¾·áÇϱâ À§ÇÏ¿© WSACleanup()À» È£ÃâÇÏ°í À©µµ¿ì¿¡ Á¾·á ¸Þ½ÃÁö WM_DESTROY¸¦ º¸³»±â À§ÇÏ¿© DestroyWindow() ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.
5-1-6. WM_DESTROYÀÇ Ã³¸®
À§ÀÇ DestroyWindow()¿¡ ÀÇÇØ À©µµ¿ì ³»ºÎÀûÀ¸·Î ¹ß»ýÇÏ´Â ¸Þ½ÃÁö·Î¼ À©µµ¿ì¸¦ Á¾·á½Ãų ¶§ »ç¿ëµÈ´Ù. ¾Æ·¡¿¡¼ PostQuitMessage() ÇÔ¼ö´Â À©µµ¿ì ¸Þ½ÃÁö Å¥¿¡ Á¾·á ¸Þ½ÃÁö¸¦ Àü¼ÛÇÑ´Ù.
5-1-7. WM_ASYNCÀÇ Ã³¸®
¼¹ö¿ÍÀÇ ¿¬°á, ¿¬°áÁ¾·á, µ¥ÀÌÅÍ ¼Û¼ö½Å µîÀº ½Ã½ºÅÛÀÇ I/O º¯È½Ã ¹ß»ýÇÏ´Â ¸Þ½ÃÁö WM_ASYNC¸¦ ÀÌ¿ëÇÏ¿© 󸮵ȴÙ. ¹ß»ýÇÑ À̺¥Æ®ÀÇ Á¾·ù¸¦ ±¸ºÐÇϱâ À§ÇÏ¿© ¸ÅÅ©·Î WSA- GETSELECTEVENT()¸¦ »ç¿ëÇÑ´Ù. WChat_Client.c¿¡¼ ó¸®ÇØ¾ß ÇÒ À̺¥Æ®ÀÇ Á¾·ù´Â FD_ CONNECT, FD_CLOSE, FD_WRITE, FD_READÀ̸ç À̵éÀ» °¢°¢ ó¸®ÇÏ´Â °ÍÀ» ¾Æ·¡¿¡ º¸¿´´Ù.
ÀÌ»óÀÌ 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¸¦ ¹ÞÁö ¾ÊÀ» ¶§¸¦ È®ÀÎÇÏ¸é ¾Ë ¼ö ÀÖ´Ù.
|