ÃÑ ÆäÀÌÁö ¼ö : 3224

Àüü ÇÔ¼ö/¿ë¾î»çÀü
Facebook Joinc ±×·ì   Joinc QA »çÀÌÆ®



joinc´Â Firefox¿Í chrome¿¡¼­ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼­´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù.

Contents

1 ³×Æ®¿öÅ© ÇÁ·Î±×·¥À» ÀÛ¼ºÇÏ´Â°Ç ¾î·Á¿î ÀÏÀÌ´Ù.
2 °´Ã¼ÁöÇâÀ» ÅëÇÑ ¼ÒÇÁÆ®¿þ¾î ǰÁú Çâ»ó
3 Á¤º¸Ã³¸® ±â¼úÀÇ ÁøÈ­
4 ACEÀÇ Æ¯Â¡
4.1 ACE°¡ Áö¿øÇÏ´Â Ç÷¿Æû
5 ACE ÇÁ·¹ÀÓ¿öÅ©
6 ¿¬°áÁöÇâ ÇÁ·ÎÅäÄݰú ºñ¿¬°áÁöÇâ ÇÁ·ÎÅäÄÝÀÇ ºñ±³
6.1 ¿¬°áÁöÇâ ÇÁ·ÎÅäÄÝ
6.2 ºñ¿¬°áÁöÇâ ÇÁ·ÎÅäÄÝ
7 ´ÙÁß Ã³¸®
7.1 NONMULTIPLEXED CONNECTIONS
8 Synchronous VS Asynchronous µ¥ÀÌÅÍ ±³È¯
8.1 ¸Þ½ÃÁö Àü´Þ°ú °øÀ¯ ¸Þ¸ð¸®
9 Socket »ìÆìº¸±â
9.1 Socket Dimensions
9.2 Socket API
9.3 Socket ÀÇ ÇѰè
9.4 ¿¹Á¦·Î º¸´Â Socket APIÀÇ ¹®Á¦Á¡
9.5 ACE Socket Wrapper Facade(12) Classes
9.6 Wrapper Facade Pattern
9.7 ACE Socket Wrapper Facades ±¸Á¶
9.8 ACE Socket Wrapper FacadesÀÇ ±ÔÄ¢
9.9 ACE Socket Addressing Classes
9.10 ACE I/O Handle Class
9.11 ACE_SOCK_Connector Ŭ·¡½º
9.12 ACE Wrapper Facades ÀÇ Æ¯Â¡
9.13 ACE_SOCK_Connector ÀÌ¿ëÇϱâ
9.14 ACE_SOCK_Stream Ŭ·¡½º
9.15 Nagle(12) ¾Ë°í¸®Áò Á¦¾î
9.16 ACE_SOCK_Acceptor Ŭ·¡½º
9.17 ACE_SOCK_Acceptor Ŭ·¡½º¸¦ »ç¿ëÇÏÀÚ
9.18 ACE_Mem_Map Ŭ·¡½º
9.19 ACE_Message_Block Ŭ·¡½º
9.19.1 2Á¾·ùÀÇ ACE_Message_Block Ŭ·¡½º
9.20 ACE_Message_BlockÀÇ ÀÌ¿ë
10 Client Application ÀÛ¼º
10.1 Logging Client
11 Logging Server ÀÛ¼º
11.1 Logging Server ÄÚµå
11.2 Logging_Handler ÀÛ¼º
11.3 Iterative Logging Server
11.4 µ¿½Ã󸮸¦ À§Çؼ­ °í·ÁÇØ¾ß ÇÒ »çÇ×
11.4.1 Iterative(¼øÂ÷Àû ó¸®) ´ë µ¿½Ã ó¸®
11.4.2 ´ÙÁß ÇÁ·Î¼¼½º ´ë ´ÙÁß ¾²·¹µå
11.5 ¾²·¹µåÇ® (Thread Pool)ÀÇ ¿î¿ë Àü·«
11.5.1 Half-Sync/Half-Async Pattern
11.5.2 Half-Sync/Half-Async PatternÀÇ ´ÜÁ¡
11.5.3 Leader/Followers architectural pattern
11.6 Thread-perRequest On-demand Spawning Strategy
12 N:1 ¿Í 1:1 ¾²·¹µå ¸ðµ¨
13 Task- vs. Message-based Concurrency Architectures
14 Overview of OS Concurrency(Çù·Â) Mechanisms
14.1 Synchronous Event Demultiplexing
14.2 ¸ÖƼ Processing ¹æ½Ä
14.3 ¸ÖƼ ¾²·¹µå ¹æ½Ä
14.4 ¾²·¹µå µ¿±âÈ­
15 ACE Event Demuxing Wrapper Facades

1 ³×Æ®¿öÅ© ÇÁ·Î±×·¥À» ÀÛ¼ºÇÏ´Â°Ç ¾î·Á¿î ÀÏÀÌ´Ù.

°ß°íÇϰí È¿À²ÀûÀ̸ç, È®Àå ¿ëÀÌÇÏ°í °Ô´Ù°¡ ´ÙÁßÀÇ Å¬¶óÀ̾ðÆ®ÀÇ ¿ä±¸¸¦ ó¸®ÇØ¾ß ÇÏ´Â ³×Æ®¿öÅ© ¾ÖÇø®ÄÉÀ̼ÇÀ» ÀÛ¼ºÇÏ´Â °ÍÀº ¸Å¿ì Èûµç ÀÏÀÌ´Ù. ¸ðµç ÀÌ·± ÇÁ·Î±×·¥À» ¸¸µé±â À§Çؼ­´Â ³×Æ®¿öÅ©¿¡ ´ëÇÑ Áö½Ä»Ó¸¸ ¾Æ´Ï¶ó ½Ã½ºÅÛ ÇÁ·Î±×·¡¹Ö¿¡ ´ëÇÑ ±íÀº Áö½ÄÀ» ÇÊ¿ä·Î ÇÑ´Ù. Ȥ½Ã³ª ´Ù¾çÇÑ Ç÷§ÆûÀ» Áö¿øÇØ¾ß Çϴ°æ¿ì´Â ´õ¿í ±×·¯ÇÏ´Ù.

ÀÌ·¸°Ô ÇÁ·Î±×·¥ÀÇ ÀÛ¼ºÀÌ º¹ÀâÇØÁö´Â °ÍÀº ´ÙÀ½°ú °°Àº ÀÌÀ¯µé ¶§¹®ÀÌ´Ù.
  • Á¾¼ÓÀûÀÎ ¹®Á¦µé
    1. ¿î¿µÃ¼Á¦º°·Î Á¦¾îÇØ¾ß ÇÏ´Â ³·Àº ¼öÁØÀÇ APIµé
    2. ¾µ¸¸ÇÏÁö ¸øÇÑ(ȤÀº ¾²±â ¾î·Á¿î) µð¹ö±ëÅø
    3. ¸Å¹ø ÀçÀÛ¼ºÇØ¾ß ÇÏ´Â ÄÄÆ÷³ÍƮȭ µÇÁö ¸øÇÑ ¾Ë°í¸®Áòµé
    4. ¸Å¹ø ÀçÀÛ¼ºÇØ¾ß ÇÏ´Â ºñ½ÁÇÑ ÀÏÀ» ÇÏ´Â ºñ½ÁÇÑ ÄÄÆ÷³ÍÆ®µé°ú »ç¿ëÀÚ Á¤ÀÇ ÇÔ¼öµé
  • µ¶¸³ÀûÀÎ ¹®Á¦µé
    1. ·Îµå¹ë·±½Ì
    2. È®À强
    3. ½ºÄÉÁ층 & µ¿±âÈ­
    4. Deadlock
À§¿Í °°Àº º¹ÀâÇÑ ¹®Á¦µé ¶§¹®¿¡ Àû´çÇÑ Ç°ÁúÀ» °¡Áö´Â ¼ÒÇÁÆ®¿þ¾î¸¦ ÀÛ¼ºÇϱâ À§Çؼ­´Â »ó´çÇÑ ½Ã°£°ú ³ë·ÂÀÌ ÅõÀڵǾî¾ß ÇÑ´Ù. ƯÈ÷ ´ÙÁß Ç÷¿ÆûÀ» Áö¿øÇÏ´Â ¼ÒÇÁÆ®¿þ¾î¸¦ ÀÛ¼ºÇÒ °æ¿ì ǰÁúÇâ»óÀ» ±â´ëÇϱâ´Â ¿©°£ ¾î·Á¿î ¹®Á¦°¡ ¾Æ´Ï´Ù. ´ÙÁß Ç÷¿Æû¿¡ ´ëÇØ¼­ ÇØ¹ÚÇÑ Áö½ÄÀ» °¡Áø °í±Þ±â¼úÀÚ°¡ ÅõÀԵǾî¾ß ±×³ª¸¶ ǰÁúÀ» º¸ÁõÇÒ ¼ö ÀÖ´Ù(´ÙÁß Ç÷¿Æû¿¡ °ÉÃļ­ ¼ÒÇÁÆ®¿þ¾î¸¦ Æ÷ÆÃÇØº» °³¹ßÀÚ¶ó¸é ±× °íÃæÀ» ÀÌÇØÇÒ °ÍÀÌ´Ù).

2 °´Ã¼ÁöÇâÀ» ÅëÇÑ ¼ÒÇÁÆ®¿þ¾î ǰÁú Çâ»ó

  • ÆÐÅÏÀ» ÅëÇÑ ¼ÒÇÁÆ®¿þ¾î ±¸Á¶¿Í µðÀÚÀÎÀÇ Àç»ç¿ë
  • OS ½Ã½ºÅÛ API¿Í ³×Æ®¿öÅ© APIÀÇ Ä¸½¶È­
    ¸¹Àº ´ÙÁß Ç÷¿ÆûÁö¿ø ¼ÒÇÁÆ®¿þ¾î °³¹ßÀÚµéÀº ÀÚÁÖ »ç¿ëµÇ´Â ½Ã½ºÅÛ/³×Æ®¿öÅ© APIµéÀ» ¿©·¯°¡Áö ¹æ¹ýÀ» ÀÌ¿ëÇØ¼­ ĸ½¶È­ ÇØ¼­ »ç¿ëÇÑ´Ù. ACE´Â ¸Å¿ì ³ôÀº ¼öÁØ¿¡¼­ ĸ½¶È­ ½ÃŲ´Ù.
  • °´Ã¼ÁöÇâ ¾ð¾îÀÇ Æ¯Â¡ÀÎ classes, dynamic binding, »ó¼Ó, parameterized typesµîÀ» »ç¿ëÇØ¼­ »ý»ê¼º Çâ»ó

°´Ã¼ÁöÇâ°ú °ü·ÃµÈ ³»¿ëµéÀº ¼­Á¡ÀÇ Àü¹®¼­ÀûµéÀ» Âü°íÇϱ⠹ٶõ´Ù.

3 Á¤º¸Ã³¸® ±â¼úÀÇ ÁøÈ­

Á¤º¸Ã³¸®¸¦ À§ÇÑ ±âº» ÀÚ¿øÀÎ CPU¿Í ³×Æ®¿öÅ©´Â ¸Å³â 3-7¹è Á¤µµ°¡ ´õ »¡¶óÁö°í ÀÖÀ¸¸ç, 2010³â °æ¿¡´Â ´ë·« ¾Æ·¡¿Í °°Àº ¼öÁرîÁö ¹ßÀüÇÒ °ÍÀ¸·Î ¿¹»óµÇ°í ÀÖ´Ù.
  • 100 GigaHz PC
  • 100 Gigabits/sec Lan
  • 100 Megabis/sec ¹«¼±È¯°æ
  • 10 Terabits/sec internet(12) backbone(12)

À̵é Çϵå¿þ¾î ÀÚ¿øÀÇ Áö¿øÀ» À§Çؼ­´Â ¾Æ·¡¿Í °°Àº Çϵå¿þ¾î¿Í ¼ÒÇÁÆ®¿þ¾î API, ÇÁ·ÎÅäÄݵéÀÇ Áö¿øÀÌ ÀÌ·ç¾îÁ®¾ß ÇÒ°ÍÀÌ´Ù.
  • Intel X86 & Power PC chipset
  • TCP/IP, ATM(12)
  • POSIX(12), & JVMs(12)
  • Middleware & components

4 ACEÀÇ Æ¯Â¡

http://www.cs.wustl.edu/~schmidt/gifs/layer3.gif

ACE´Â ´ÙÀ½°ú °°ÀÌ °³¹ßµÇ¾îÁö°í ÀÖ´Ù.
  • Open Source
  • 200,000 ¶óÀÎÁ¤µµÀÇ C++
  • ¿¬Àοø 40¸íÀÌ»óÀÇ °³¹ßÀηÂ
  • ´Ù¾çÇÑ OS Ç÷¿ÆûÀÇ Áö¿ø

4.1 ACE°¡ Áö¿øÇÏ´Â Ç÷¿Æû

  • 32/64bit Windows, Win CE
  • Redhat, Debian, SuSe Linux
  • macintosh OS X
  • SunOS4.x, Solaris, SGI IRIX, HP-UX, Digital Unix, AIX, DG/UX, SCO OpenServer, UnixWare, NetBSD, FreeBSD µî ´ëºÎºÐÀÇ Unixµé
  • VxWorks, OS/9, Chorus, LynxOS, Pharlap TNT, QNX Neutrino, RTP, RTEMS, pSoS µîÀÇ ¸®¾óŸÀÓ ¿î¿µÃ¼Á¦
  • OpenVMS, MVS OpenEdition, Tandem NonStop-Ux, Cray UNICOSµîÀÇ ¿£ÅÍÇÁ¶óÀÌÁî ½Ã½ºÅÛ

ACE´Â À§ÀÇ Ç÷¿Æû¿¡¼­ »ç¿ëÇÏ´Â ¸ðµç C++ ÄÄÆÄÀÏ·¯¿¡¼­ »ç¿ëÀÌ °¡´É.

5 ACE ÇÁ·¹ÀÓ¿öÅ©

+------------+        +------------+         +------------+ 
| Acceptor   |------->| Reactor    |<--------| Proactor   |  
| Connector  |        |            |         |            |  
+------------+        +------------+         +------------+ 
 
+--------------+      +------------+         +------------+ 
| Service      |----->| Streams    |-------->| Task       | 
| Configurator |      |            |         |            | 
+--------------+      +------------+         +------------+ 
 
ACE Framework Inversion of Control
Reactor & Proactor µ¿±â/ºñµ¿±â·Î ¹ß»ýÇÏ´Â À̺¥Æ®µéÀÇ Ã³¸®¸¦ À§ÇÑ ÇÁ·Î¼¼½º È£Ãâ |
Service Configurator ¼­ºñ½º °´Ã¼ÀÇ ÃʱâÈ­, ÁßÁö, Àç°¡µ¿, Á¾·áµîÀ» À§ÇÑ ÇÁ·Î¼¼½º È£Ãâ
Acceptor-Connector ¿¬°áÀ» À§ÇÑ ¼­ºñ½º ÃʱâÈ­ ÇÁ·Î¼¼½º È£Ãâ
Stream streamÀ¸·Î ºÎÅÍÀÇ µ¥ÀÌÅÍ ÀÔÃâ·Â°ú ÃʱâÈ­¸¦ À§ÇÑ ÇÁ·Î¼¼½º È£Ãâ

6 ¿¬°áÁöÇâ ÇÁ·ÎÅäÄݰú ºñ¿¬°áÁöÇâ ÇÁ·ÎÅäÄÝÀÇ ºñ±³

¸¹Àº ÇÁ·ÎÅäÄݵéÀº º»°ÝÀûÀ¸·Î µ¥ÀÌÅ͸¦ ÀÔÃâ·ÂÇϱâ Àü¿¡ ¿¬°áÀ» ¸Î´Â ÀÛ¾÷À» ÇÑ´Ù. °¡Àå ´ëÇ¥ÀûÀÎ °æ¿ì´Â ÀüÈ­¸¦ ÇÏ´Â °æ¿ì´Ù. ÀüÈ­¸¦ ÇØ¼­ º»°ÝÀûÀ¸·Î ´ëÈ­¸¦ ³ª´©±â Àü¿¡ º¸Åë ´ëÈ­ÀÇ »ó´ë°¡ ¿Ã¹Ù¸¥Áö È®ÀÎÇϱâ À§ÇÑ ÀÛ¾÷ÀÌ ÀÌ·ç¾îÁø´Ù.
 Connector              Accoptor 
    |                       | 
    |  1. SYN               | 
    | --------------------> | 
    | <-------------------- | 
    |            2. SYN/ACK | 
    |  3. ACK               | 
    | --------------------> | 
    |  4.                   | 
    | <-------------------> | 
    |                       | 
 TCP/IP 3-Way handshake 
 
 
 1. Àú´Â ´©±¸ÀÔ´Ï´Ù. ¾Æ¹«°³¾¾ ¸Â½À´Ï±î ? 
 2. ³» ´©±¸´©±¸ ¸Â½À´Ï´Ù. 
 3. ÇÏ°í ½ÍÀº ¾ê±â°¡ À־ ÀüÈ­ µå·È½À´Ï´Ù. 
 4. ÀÌ·± Àú·± ´ëÈ­ 
 
³×Æ®¿öÅ© »óÀÇ µ¥ÀÌÅͱ³È¯ ¿ª½Ã À§¿¡¼­ ó·³ ¿¬°áÀ» ¸Î´Â °úÁ¤À» °ÅÄ¡´Â ÇÁ·ÎÅäÄÝÀÌ ÀÖÁö¸¸ ±×·¸Áö ¾ÊÀº °æ¿ìµµ ÀÖ´Ù. ¾î¶² ÇÁ·ÎÅäÄÝÀ» »ç¿ëÇÒÁö´Â ¸¸µé°íÀÚ ÇÏ´Â ³×Æ®¿öÅ© ¼­ºñ½º¿¡ µû¶ó¼­ ´Þ¶óÁú ¼ö ÀÖ´Ù.

6.1 ¿¬°áÁöÇâ ÇÁ·ÎÅäÄÝ

  1. ½Å·ÚÇÒ¼ö ÀÖÀ¸¸ç, ¼­ºñ½º´Â Áߺ¹µÇÁö ¾ÊÀ¸¸ç, ¿¬¼ÓÀûÀ¸·Î ÀÌ·ç¾îÁú ¼ö ÀÖ´Ù. µ¥ÀÌÅÍ ´©¶ôÀ» Çã¶ôÇÒ ¾ø´Â Áß¿äÇÑ ¼­ºñ½º¿¡ »ç¿ëÇÑ´Ù.
  2. TCP, ATM°ú °°Àº ÇÁ·ÎÅäÄÝÀÌ ÀÖ´Ù.

6.2 ºñ¿¬°áÁöÇâ ÇÁ·ÎÅäÄÝ

  1. ¸Þ½ÃÁö ÁöÇâ ¼­ºñ½º¿¡ ÁÖ·Î »ç¿ëµÈ´Ù. ¸Þ½ÃÁöµéÀº µ¶¸³ÀûÀ¸·Î °æ·Î°¡ ÇÒ´çµÇ¾î¼­ Àü´ÞµÈ´Ù.
  2. UDP, IP °°Àº ÇÁ·ÎÅäÄÝÀÌ ÀÖ´Ù.

7 ´ÙÁß Ã³¸®

´Ù¼öÀÇ Å¬¶óÀÌ¾ðÆ®¸¦ ó¸®ÇÏ´Â ¹æ¹ýÀ¸·Î MULTIPLEXED CONNECTION °ú NONMULTIPLEXED CONNECTIONS µÎ°¡Áö°¡ ÀÖ´Ù.
==== MULTIPLEXED CONNECTION =====
´Ù¼öÀÇ Å¬¶óÀÌ¾ðÆ®¿¡¼­ µé¾î¿À´Â ¿¬°á ¿ä±¸¸¦ ÇϳªÀÇ ÇÁ·Î¼¼½º¿¡¼­ ´Ù¼öÀÇ ¾²·¹µå¸¦ µ¿½Ã¿¡ Á¦¾îÇÏ´Â ¹æ½ÄÀ¸·Î ó¸®ÇÑ´Ù.
  +---------------+             +---------------+ 
  | CLIENT THREAD |             | SERVER THREAD | 
  |               |             |               | 
  | CL1->CL2->CL3 |             | SR1->SR2->SR3 | 
  |  |         |  |             |  |         |  | 
  +--|---------|--+             +--|---------|--+ 
     +---------+                   +---------+ 
          |                             | 
          +-----------------------------+  
                 TCP/IP Connection 
 

´ëüÀûÀ¸·Î ¸®¼Ò½º¸¦ Àû°Ô Àâ¾Æ¸Ô°í, È¿À²ÀûÀ¸·Î ÀÛµ¿Çϱâ´Â ÇÏÁö¸¸ ÇÁ·Î±×·¡¹Ö Çϱâ Èûµé´Ù¶ó´Â ´ÜÁ¡À» °¡Áø´Ù.

7.1 NONMULTIPLEXED CONNECTIONS

°¢°¢ÀÇ Å¬¶óÀÌ¾ðÆ®´Â µ¶¸³µÈ ¼­ºñ½º¸¦ À§Çؼ­ ´Ù¸¥ ¿¬°áÀ» À¯ÁöÇÑ´Ù. ´ÙÁß ÇÁ·Î¼¼½º ¹æ½ÄÀ¸·Î ±¸ÇöµÇ´Â °æ¿ì°¡ ¸¹´Ù.
  +---------------+             +---------------+ 
  | CLIENT THREAD |             | SERVER THREAD | 
  |               |             |               | 
  | CL1->CL2->CL3 |             | SR1->SR2->SR3 | 
  |  |    |    |  |             |  |    |    |  | 
  +--|----|----|--+             +--|----|----|--+ 
     +----|----|-------------------+    |    | 
          +----|------------------------+    | 
               +-----------------------------+ 
                   TCP/IP Connection 
 
ÇÁ·Î¼¼½º°¡ ¸íÈ®ÇØ¼­ Á¦¾îÇϱ⠽±°í, µ¿±âÈ­ ±â¼úÀ» À§ÇÑ ¸Þ¸ð¸®/ÆÄÀÏ Àá±ÝµîÀÌ ÇÊ¿äÇÏÁö ¾Ê¾Æ¼­ ÇÁ·Î±×·¥À» ÀÛ¼ºÇϱ⠽±´Ù¶ó´Â ÀåÁ¡À» °¡ÁöÁö¸¸, ¸¹Àº ÀÚ¿øÀ» ¼Ò¸ðÇÑ´Ù´Â ´ÜÁ¡À» °¡Áø´Ù. ´Ù¼öÀÇ ¿¬°á°ú ¸¹Àº µ¥ÀÌÅ͸¦ ó¸®Çϱâ À§Çؼ­´Â ÁÁÀº ¹æ¹ýÀÌ ¾Æ´Ï´Ù.

8 Synchronous VS Asynchronous µ¥ÀÌÅÍ ±³È¯

Synchronous/Asynchronous ¼ÒÄϰú È¥µ¿ÇÏÁö ¸»±â ¹Ù¶õ´Ù.

  1. Synchronous

      Server                   Client  
         |          Request 1   | 
         | <------------------- | 
         |  Response 1          | 
         | -------------------> | 
        ---                     | 
         |          Request 2   | 
         | <------------------- | 
         |  Response 2          | 
         | -------------------> | 
        ---                     | 
         |          Request 3   | 
         | <------------------- | 
         |  Response 3          | 
         | -------------------> | 
     
    ¿äû°ú ÀÀ´äÀÌ ÇÁ·ÎÅäÄݽÖÀ¸·Î 󸮵ȴÙ. ÇϳªÀÇ ½ÖÀ̹ǷΠÇϳªÀÇ ¿äûÀÌ ³¡³ª±â Àü¿¡´Â ´ÙÀ½ ÇÁ·Î¼¼½º·Î ÁøÇàµÇÁö ¾Ê´Â´Ù. Á÷°üÀûÀ¸·Î µ¥ÀÌÅ͸¦ ó¸®ÇÒ ¼ö ÀÖÀ¸¸ç, ½±°Ô ±¸Çö°¡´ÉÇÏ´Ù. ¿äû°ú ÀÀ´äÀ» ÅëÇØ¼­ ¼­¹ö/ÇÁ·Î¼¼½º°£ Sync¸¦ ¸ÂÃß¾î¾ß ´ÙÀ½À¸·Î ÁøÇàÀÌ °¡´ÉÇÏ´Ù.

  2. Asynchronous

      Server                   Client  
         |          Request 1   | 
         | <------------------- | 
         |          Request 2   | 
         | <------------------- | 
         |  Response 1          | 
         | -------------------> | 
         |          Request 3   | 
         | <------------------- | 
         |  Response 2          | 
         | -------------------> | 
         |  Response 3          | 
         | -------------------> | 
     
¿äû°ú ¿äû¿¡ ´ëÇÑ ÀÀ´äÀ» µ¿±âÈ­ ½Ã۱â À§Çؼ­ ±â´Ù¸®Áö ¾Ê´Â´Ù. µ¿½Ã¿¡ ´Ù¼öÀÇ Å¬¶óÀÌ¾ðÆ®·Î ºÎÅÍÀÇ ¿äûÀ» ´ë±â½Ã°£ ¾øÀÌ È¿À²ÀûÀ¸·Î ó¸®ÇÒ ¼ö ÀÖ´Ù. ±×·¸Áö¸¸ 󸮰á°ú¸¦ Á¦¾îÇϱⰡ ±î´Ù·Ó´Ù´Â ´ÜÁ¡À» °¡Áø´Ù. ÀÏÀ» ¹Þ¾ÆµéÀÌ´Â »ç¶÷°ú ó¸®ÇÏ´Â »ç¶÷ÀÌ µû·Î ÀÖ´Ù°í »ý°¢ÇÒ ¼ö ÀÖ°Ú´Ù.

8.1 ¸Þ½ÃÁö Àü´Þ°ú °øÀ¯ ¸Þ¸ð¸®

   +-------------+                  +-------------+ 
   | CLIENT      |                  | SERVER      |  
   |             |                  |             | 
   |             |                  |             | 
   +-------------+                  +-------------+ 
        |                                   | 
        | MSG --->                          | 
        +-----------------------------------+ 
                       IPC(12) 
 
¸Þ½ÃÁö Àü´Þ(Message Passing)´Â IPC ¼³ºñ¸¦ ÀÌ¿ëÇØ¼­ µ¥ÀÌÅ͸¦ Àü´ÞÇÑ´Ù. °³¹ßÀÚµéÀº ó¸®ÇؾßÇÒ µ¥ÀÌÅ͸¦ ¸íÈ®È÷ Çϱâ À§Çؼ­ ÇÁ·ÎÅäÄÝÀ» Á¤ÀÇÇØ¼­ »ç¿ëÇÏ°Ô µÈ´Ù.
  1. µ¥ÀÌÅÍ Æ÷¸Ë°ú µ¥ÀÌÅÍ¿¡ Æ÷Ç﵃ ³»¿ë
  2. µ¥ÀÌÅÍÀÇ ½ÃÀÛ°ú Á¾·á¸¦ ¾Ë·ÁÁÖ±â À§ÇÑ ¹æ¹ý(¼¼¼Ç À¯Áö)
  3. µ¥ÀÌÅÍ Àü´Þ ¹æ½Ä(unicast(12), multicast(12), boradcast(12))

   +-------------+                  +-------------+ 
   | CLIENT      |                  | SERVER      |  
   |             |                  |             | 
   |      +--------------------------------+      |  
   |      |      |                  |      |      | 
   +------|------+                  +------|------+ 
          |    °øÀ¯ ¸Þ¸ð¸® ¿µ¿ª            |  
          |                                | 
          +--------------------------------+ 
 
°øÀ¯¸Þ¸ð¸®´Â ´Ù¼öÀÇ ÇÁ·Î¼¼½º°¡ ÇϳªÀÇ ¸Þ¸ð¸® ¿µ¿ªÀ» ÅëÇØ¼­ µ¥ÀÌÅ͸¦ ±³È¯ÇÒ ¼ö ÀÖµµ·Ï Çã¿ëÇÑ´Ù. ´Ù¼öÀÇ ÇÁ·Î¼¼½º°¡ ¸Þ½ÃÁö Àü´Þ ¹æ½ÄÀ» ÀÌ¿ëÇÒ °æ¿ì µ¿ÀÏÇÑ µ¥ÀÌÅͰ¡ ¿©·¯¹ø º¹»çµÈ´Ù´Â ´ÜÁ¡ÀÌ Àִµ¥, °øÀ¯¸Þ¸ð¸®¸¦ ÀÌ¿ëÇÒ °æ¿ì ÇϳªÀÇ ¸Þ½ÃÁö¸¸ »ç¿ëÇÏ¸é µÇ¹Ç·Î È¿À²ÀÌ ³ô¾ÆÁö°Ô µÈ´Ù. ±×·¯³ª Á¦¾îÇϱ⠱î´Ù·Ó´Ù´Â ´ÜÁ¡À» °¡Áø´Ù.

9 Socket »ìÆìº¸±â

Socket´Â ¿î¿µÃ¼Á¦¿¡ »ó°ü¾øÀÌ ³×Æ®¿öÅ© Åë½Å ÇÁ·Î±×·¡¹ÖÀÌ °¡´ÉÇϵµ·Ï ÀϹÝÀûÀÎ API¸¦ Á¦°øÇÑ´Ù. Socket´Â ´ÙÀ½°ú °°Àº Ư¡À» °¡Áø´Ù.

  • Socket´Â TCP/IP ÇÁ·ÎÅäÄÝÀ» ±â¹ÝÀ¸·Î BSD Unix »ç¿¡¼­ C¾ð¾î¸¦ ÅëÇØ¼­ °³¹ßµÇ¾ú´Ù.
  • 5°³ÀÇ Ä«Å×°í¸®¿¡ ¾à 20°³ Á¤µµÀÇ ÇÔ¼öµé·Î ±¸¼ºµÇ¾î ÀÖ´Ù.
  • remote »Ó¸¸ ¾Æ´Ï¶ó local ¿µ¿ª¿¡¼­ÀÇ Åë½Åµµ Áö¿øÇÑ´Ù. local¿µ¿ª¿¡¼­ÀÇ Åë½ÅÀ» Áö¿øÇÒ°æ¿ì process°£ ³»ºÎÅë½Å(IPC(12))À» À§ÇÑ ¿ëµµ·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù.
  • Unix(:12)¿¡¼­ ¼ÒÄÏÀº ÀÏ¹Ý ÆÄÀÏó·³ ´Ù·ç¾îÁö¸ç ÆÄÀϰú µ¿ÀÏÇÑ I/O Á¦¾î°¡ °¡´ÉÇÏ´Ù. ±×·¯³ª À©µµ¿ìÀÇ °æ¿ì´Â ¿¹¿Ü´Ù.

9.1 Socket Dimensions

socketd.gif

  1. Åë½ÅŸÀÔ¿¡ µû¸¥ ºÐ·ù
    • stream °ú datagrams ¹æ½ÄÀÌ ÀÖ´Ù. stream ¹æ½ÄÀÇ °æ¿ì ¼¼¼ÇÀ» ¸Î°í È帧À» Á¦¾îÇÏ´Â ¹Ý¸é(¼¼¼Ç´ÜÀ§ ó¸®), datagrams ¹æ½ÄÀº µ¥ÀÌÅͱ׷¥ ´ÜÀ§·Î µ¥ÀÌÅ͸¦ ó¸®ÇÑ´Ù. TCP´Â stream¹æ½Ä, UDP´Â datagrams ¹æ½Ä ÇÁ·ÎÅäÄÝÀÌ´Ù.
  2. Åë½Å¹× ¿¬°á ±ÔÄ¢
    • ÀϹÝÀûÀ¸·Î Ŭ¶óÀÌ¾ðÆ®°¡ ´Éµ¿ÀûÀ¸·Î ¿¬°áÀ» ¿äûÇϰí, ¼­¹ö´Â ¼öµ¿ÀûÀÎ ÀÔÀå¿¡¼­ ±â´Ù¸°´Ù.
  3. Åë½Å ¿µ¿ª(domain)
    • ·ÎÄÿµ¿ª¿¡¼­ÀÇ Åë½Å°ú ¿ø°Ý¿µ¿ª¿¡¼­ÀÇ Åë½ÅÀ¸·Î ³ª´¶´Ù. ·ÎÄÿµ¿ª¿¡¼­¶ó¸é ÇÁ·Î¼¼½º°£ Åë½Å(IPC(12))°¡ µÉ °ÍÀÌ´Ù.

9.2 Socket API

socket layer ¼Ò°³¹®¼­¸¦ Âü°íÇϱ⠹ٶõ´Ù.

9.3 Socket ÀÇ ÇѰè

  • ±¸Á¶È­ µÇ¾î ÀÖÁö ¾ÊÀ¸¸ç, Çü½ÄÀÌ ¾ø°í, »ç¿ëÇϱ⠽±Áö ¾Ê´Ù.
    ¿ì¼± API(12)´Â »ó¼ÓÀÇ °³³äÀÌ ¾ø´Â ÇÔ¼öÀÇ ¼±ÇüÀûÀÎ ³ª¿­·Î µÇ¾î ÀÖ´Ù. °³¹ßÀÚ´Â ³·Àº ¼öÁØ¿¡¼­ APIÀÇ °¢ ÇÔ¼öµé¿¡ ´ëÇØ¼­ ¸íÈ®È÷ ÀÌÇØ¸¦ Çϰí ÀÖ¾î¾ß ÇÑ´Ù. Ŭ·¡½ºÈ­ µÇ¾î ÀÖ´Â ´Ù¸¥ API¸¦ ÀÌ¿ëÇØ¼­ ÇÁ·Î±×·¥À» ¸¸µé°æ¿ì º¸Åë 70Á¡ ÀÌ»óÀÇ ÀÏÁ¤ÇÑ ¼öÁØÀÇ Ç°ÁúÀ» À¯ÁöÇÒ ¼ö ÀÖÁö¸¸, ±¸Á¶È­ µÇ¾î ÀÖÁö ¾ÊÀº Socket°ú °°Àº API¸¦ °¡Áö°í ÇÁ·Î±×·¥À» ÀÛ¼ºÇÒ °æ¿ì °³¹ßÀÚÀÇ ¿ª·®¿¡ µû¶ó¼­ 100-10 ±îÁöÀÇ Ç°ÁúÀÇ Â÷À̸¦ º¸¿©ÁØ´Ù.
  • ÇÔ¼ö À̸§µé°£ÀÇ ¿¬°ü¼ºÀ» ã±â°¡ ½±Áö ¾Ê´Ù. Á¶°¢Á¶°¢ Âɰ³Á® ÀÖ´Ù. ´ÙÀ½ ÇÔ¼öµé °£ÀÇ ¿¬°ü¼ºÀ» ã¾Æº¸±â ¹Ù¶õ´Ù.
  • À©µµ¿ìÀÇ °æ¿ì ¿ø°ÝÅë½ÅÀ» À§ÇÑ I/O¿Í ÆÄÀÏ I/O°¡ ºÐ¸®°¡ µÈ´Ù. ¿¹¸¦ µéÀÚ¸é ÆÄÀÏÀ» ÀаíÀÚ ÇÒ°æ¿ì À©µµ¿ì´Â ReadFile¿Í WriteFile °°Àº ÇÔ¼ö¸¦ »ç¿ëÇÒ °ÍÀÌ´Ù. ±×·¯³ª À¯´Ð½º´Â ÆÄÀÏ I/O¿Í Åë½Å I/O¸¦ À§ÇÑ ÇÔ¼öÀÇ À̸§ÀÌ µ¿ÀÏÇÏ´Ù. À̰ÍÀº ÀåÁ¡ÀÌ µÉ ¼öµµ ÀÖÁö¸¸ ´ÜÁ¡ÀÌ µÉ ¼öµµ ÀÖ´Ù.

    // ¼ÒÄÏ¿¡¼­ Àо ÆÄÀÏ·Î ¾²´Â ÄÚµå, ÃæºÐÈ÷ Çê°¥¸± ¼ö ÀÖÀ» °ÍÀÌ´Ù. 
    n = read(s_handle, buf, len); 
    write(f_handle, buf, n); 
     
  • °°Àº ÇÔ¼ö°¡ ¿î¿µÃ¼Á¦¿¡ µû¶ó ´Ù¸¥ ¸®ÅϰªÀ» º¸¿©ÁØ´Ù.
  • ³Ê¹« ³·Àº ¼öÁØ¿¡¼­ ´Ù·ç¾î¾ß ÇÑ´Ù.
    1. ³·Àº ¼öÁØ¿¡¼­ ´Ù·é ´Ù´Â °ÍÀº, °æÇèÀÌ ÃæºÐÇÏÁö ¾ÊÀ» °æ¿ì ½Ç¼ö¸¦ ÇÒ ¼ö ÀÖÀ½À» ÀǹÌÇÑ´Ù. °¡Àå ÈçÇÑ ½Ç¼ö´Â byte order°ú °ü·ÃµÈ ¹®Á¦ÀÏ °ÍÀÌ´Ù.
    2. ÇÔ¼ö¸¦ À߸ø »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    3. sockaddr ±¸Á¶Ã¼¸¦ ¿ÏÀüÈ÷ ¸Ó¸®¿¡ ´ã¾ÆµÎ°í ÀÖ±â¶õ ½±Áö ¾Ê´Ù. ÇÔ¼ö¸¦ »ç¿ëÇϱâ À§Çؼ­ ¸Å¹ø ¸Þ´º¾óÀ» µÚÀû°Å·Á¾ß ÇÑ´Ù.
  • º¹À⼺ÀÇ Áõ°¡
    1. ´Ù¾çÇÑ ÇÁ·ÎÅäÄݵ鿡 ´ëÇØ¼­ Áö½ÄÀ» °¡Áö°í ÀÖ¾î¾ß ÇÑ´Ù.
    2. broadcasting, async I/O, non blocking I/O, urgent data delivery¿Í °°Àº ´Ù¾çÇÑ ¿É¼Çµé¿¡ ´ëÇØ¼­ ¾Ë°í ÀÖ¾î¾ß ÇÑ´Ù.

9.4 ¿¹Á¦·Î º¸´Â Socket APIÀÇ ¹®Á¦Á¡

// ÀÎŬ·çµå ½ÃÄÑ¾ß ÇÏ´Â Çì´õÆÄÀÏÀÇ À̸§Àº ¿î¿µÃ¼Á¦¸¶´Ù ´Ù¸¦ ¼ö ÀÖ´Ù. 
// Á¦´ë·Î ó¸®ÇÒ·Á¸é ¶§·Î´Â ÁßøµÇ±â ±îÁö ÇÏ´Â ifdef¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. 
#include <sys/types.h> 
#include <sys/socket.h> 
 
const int PORT_NUM = 10000; 
 
int echo_server() 
{ 
    struct sockaddr_in addr; 
     
    // ÀÚÁÖ addr_len¿¡ sizeof(sockaddr_in)À» ÇØÁà¾ß ÇÑ´Ù´Â °É »©¸Ô°ï ÇÑ´Ù.  
    int addr_len; 
 
    char buf[BUGSIZE]; 
 
    // ¼ÒÄÏÀÌ intÇüÀÌ´Ù. ÀÎÁöÇϱ⠽±Áö ¾Ê´Ù. 
    int n_handle; 
 
    int s_handle = socket(PF_UNIX, SOCK_DGRAM, 0); 
     
    // ¸®Åϰª ¿ª½Ã Á÷°üÀûÀÌÁö ¾Ê´Ù. 
    if (s_handle == -1) return -1; 
 
    addr.sin_family = AF_INET;       // ÇÁ·ÎÅäÄݰú family¸¦ À߸ø »ç¿ëÇϰí ÀÖ´Ù. 
    addr.sin_port = PORT_NUM;        // À߸øµÈ byte order 
    addr.sin_addr.addr = INADDR_ANY; // »ç¿ëÇÏÁö ¾ÊÀº ±¸Á¶Ã¼ ¸â¹ö. 
 
    if (bind (s_handle, (struct sockaddr *) &addr, sizeof addr) == -1) 
        return -1; 
 
    // listen() ÇÔ¼ö¸¦ »©¸Ô¾ú±º¿ä.     
 
    // s_handle´Â SOCK_DGRAM ÀÌ´Ù. ¹Ì½º¸ÅÄ¡´Ù.  
    if (n_handle = accept(s_handle, (struct sockaddr *)&addr, 
            &addr_len) != -1) 
    { 
        int n; 
        while((n = read(s_handle, buf, sizeof(buf)) > 0) 
        { 
            // n byte¿¡¼­ ¾î¶²ÀÏÀÌ ÀϾÁö º¸ÁõÇÒ ¼ö ¾ø´Ù. 
            write(n_handle, buf, n);  
        } 
        close(n_handle); 
    } 
    return 0; 
 
100¶óÀεµ ¾ÈµÇ´Â ªÀº Äڵ忡¼­ 10°³°¡ ³Ñ´Â ¿À·ù°¡ ¹ß»ýµÇ¾ú´Ù. À§ÀÇ ¿À·ùµéÀº ¼ÒÄÏ ÇÁ·Î±×·¡¹Ö Çϸ鼭 (ºñ·Ï °æÇ踹Àº °³¹ßÀÚ¶ó ÇÏ´õ¶óµµ) ÈçÈ÷ °ÞÀ» ¼ö ÀÖÀ» °ÍÀÌ´Ù.

9.5 ACE Socket Wrapper Facade(12) Classes

ACE´Â C++ÀÇ Å¬·¡½ºÀÇ ¸ðÀ½À̸ç, Socket APIÀÇ ¹®Á¦µéÀ» ÇØ°áÇϰí ÀÖ´Ù.
  • Áõ°¡µÈ type-safety
  • portability
  • ÀϹÝÀûÀÎ ¸ñÀû¿¡ °£´ÜÇÏ°Ô »ç¿ëÇÒ ¼ö ÀÖ´Ù.
  • ³ôÀº ¼öÁØ¿¡¼­ ºí·°´ÜÀ§ÀÇ °³¹ßÀÌ °¡´ÉÇÏ´Ù.

ACE Ŭ·¡½º ¼³¸í
ACE_Addr ACE ³×Æ®¿öÅ© ¾îµå·¹½Ì °èÃþÀÇ ÃÖ»óÀ§ ·çÆ®
ACE_INET_Addr ÀÎÅͳݿµ¿ª ÁÖ¼Ò family
ACE_IPC_SAP IPC Wrapper °èÃþÀÇ ÃÖ»óÀ§ ·çÆ® |
ACE_SOCK Socket°ü·Ã °èÃþÀÇ ÃÖ»óÀ§ ·çÆ®
ACE_SOCK_Connector acceptor¿¡ ¿¬°á¿äûÀ» ÇÏ°í »õ·Î¿î Åë½Åä³ÎÀ» »ý¼º
ACE_SOCK_IO µ¥ÀÌÅÍ Àü¼Û ¸ÞÄ¿´ÏÁò Á¦°ø
ACE_SOCK_Acceptor connector·ÎºÎÅÍÀÇ ¿¬°á¿äû¿¡ ´ëÇØ ÀÀ´äÀ» ÇÏ°í »õ·Î¿î Åë½Åä³ÎÀ» »ý¼º

ace_class.gif

9.6 Wrapper Facade Pattern

³×Æ®¿öÅ© ¾îÇø®ÄÉÀ̼ÇÀ» ¸¸µé±â À§Çؼ­´Â Socket »Ó¸¸ ¾Æ´Ï¶ó file, thread, process, IPC¿Í °°Àº ¿î¿µÃ¼Á¦¿¡¼­ Á¦°øÇÏ´Â ´Ù¾çÇÑ ¼­ºñ½º¸¦ Ȱ¿ëÇØ¾ß¸¸ÇÑ´Ù. ¿î¿µÃ¼Á¦´Â ³·Àº ¼öÁØÀÇ C·Î Á¢±Ù°¡´ÉÇÑ API¸¦ Á¦°øÇÒ »ÓÀÌ´Ù.

ÀÌ·¯ÇÑ ³·Àº ¼öÁØÀÇ API´Â °ß°íÇϰí, È¿À²ÀûÀÎ ¾îÇø®ÄÉÀ̼ÇÀÇ °³¹ßÀ» ¾î·Æ°Ô ¸¸µç´Ù.

À§ÀÇ ¹®Á¦¸¦ ÇØ°áÇϱâ À§Çؼ­ Wrapper Facade Design Pattern(ÀÌÇÏ P2)À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. P2´Â ³·Àº ¼öÁØÀÇ API¸¦ Á÷Á¢ È£ÃâÇÏÁö ¾Ê°í Æ÷Àå½ÃÅ´À¸·Î½á ¹®Á¦¸¦ ȸÇÇÇÑ´Ù.

P2´Â °´Ã¼ÁöÇâÀûÀÌÁö ¾ÊÀº APIÀÇ ÇÔ¼ö¿Í µ¥ÀÌÅ͵éÀ» ĸ½¶È­ÇÏ°í °´Ã¼ÁöÇâ Ŭ·¡½º¸¦ ÀÎÅÍÆäÀ̽º·Î °³¹ßÀÚ¿¡°Ô Á¦°øÇÏ°Ô µÈ´Ù. ÀÌ·Î½á °³¹ßÀÚ´Â °ß°íÇϰí À¯Áöº¸¼ö°¡ ¿ëÀÌÇÑ ¾îÇø®ÄÉÀ̼ÇÀ» °³¹ßÇÒ ¼ö ÀÖ°Ô µÈ´Ù.

9.7 ACE Socket Wrapper Facades ±¸Á¶

´ÙÀ½Àº ACE Socket Wrapper facadesÀÇ ±¸Á¶ÀÌ´Ù. ÀÎÅÍ³Ý ¿µ¿ª°ú IPC¿µ¿ªÀ¸·Î ³ª´©¾î¼­ º¸¿©ÁÖ°í ÀÖ´Ù.
acewrapperclass.gif

ACE Socket wrapper facade class´Â ´ÙÀ½°ú °°Àº ±â´ÉµéÀ» Á¦°øÇÑ´Ù.
  • ACE_SOCK_*
    ÀÎÅÍ³Ý ¿µ¿ª ¼ÒÄÏ APIÇÔ¼öµéÀ» ĸ½¶È­ ½ÃŲ Ŭ·¡½º
  • ACE_L_SOCK_*
    Unix ¿µ¿ª(Local) ¼ÒÄÏ APIÇÔ¼öµéÀ» ĸ½¶È­ ½ÃŲ Ŭ·¡½º

9.8 ACE Socket Wrapper FacadesÀÇ ±ÔÄ¢

Socket API¿¡¼­ ´Éµ¿ÀûÀ¸·Î ¿¬°áÇϱâ À§ÇÑ connect()ÇÔ¼ö¿Í ´Éµ¿ÀûÀ¸·Î ¿¬°áÇϱâ À§Çؼ­ accept()ÇÔ¼ö¸¦, ¸¶Áö¸·À¸·Î Åë½ÅÀ» À§Çؼ­ read(), write()ÇÔ¼ö¸¦ »ç¿ëÇÏ´Â °Í°ú ¸¶Âù°¡Áö·Î, active connection role °ú passive connection role, communication roleÀ» °¡Áö°í ÀÖ´Ù.
  1. active connection role(ACE_SOCK_Connector)Àº ¿ø°ÝÁö·Î ¿¬°áÀ» ÃʱâÈ­ÇÏ´Â ±ÔÄ¢À» °¡Áø´Ù.
  2. passive connection role(ACE_SOCK_Acceptor)Àº ¿ø°ÝÁöÀÇ ¿¬°áÀ» ¹Þ¾ÆµéÀÌ´Â ±ÔÄ¢À» °¡Áø´Ù.
  3. communication role(ACE_SOCK_Stream)Àº ¿¬°áÀÌ µÈÈÄ ¾îÇø®ÄÉÀ̼ǰü µ¥ÀÌÅ͸¦ ±³È¯Çϱâ À§ÇÑ ±ÔÄ¢À» °¡Áø´Ù.
 +----------------------------+                      +----------------------------+ 
 | SERVER                     |                      | CLIENT                     |  
 | PASSIVE CONNECTION ROLE    |                      | PASSIVE CONNECTION ROLE    | 
 |                            |                      |                            | 
 | SOCK_Acceptor              |                      | SOCK_Acceptor              | 
 | SOCK_Stream                |                      | SOCK_Stream                | 
 | accept()     <-------------|----------------------|-connect()                  | 
 | send()/recv()  <-----------|----------------------|>send()/recv()              | 
 | close()                    |          ^           | close()                    | 
 +----------------------------+          |           +----------------------------+ 
                                         | 
                                 communication role 
 

9.9 ACE Socket Addressing Classes

Addressing Ŭ·¡½º´Â Socket°¡ ´Ù¾çÇÑ Addressing ¿µ¿ªÀ» ´Ù·ç¾î¾ß ÇÔÀ¸·Î½á ¹ß»ýÇÒ ¼ö ÀÖ´Â ¹®Á¦Á¡À» ÇØ°áÇϰí ÀÖ´Ù. Àú¼öÁØÀÇ (±»ÀÌ ¾ËÇÊ¿ä´Â ¾øÁö¸¸ º¹ÀâÇÑ) ºÎºÐÀ» ¼û±â°í, °èÃþÈ­ ½ÃÅ´À¸·Î½á ¿î¿µÃ¼Á¦¿¡ °ü°è¾øÀÌ µ¿ÀÏÇÑ ÀÎÅÍÆäÀ̽º¸¦ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇØÁØ´Ù.
                           +----------+ 
                           | ACE_Addr | 
                           +----------+ 
                                ^ 
                                | 
      +-------------------------------------------------------+ 
      |          |          |          |          |           | 
      |          |          |          |          |           | 
  +-------+  +-------+  +-------+  +-------+  +-------+   +-------+ 
  | ACE   |  | ACE   |  | ACE   |  | ACE   |  | ACE   |   | ACE   | 
  | SPIPE |  | INET  |  | DEV   |  | UNIX  |  | FILE  |   | MEM   | 
  | Addr  |  | Addr  |  | Addr  |  | Addr  |  | Addr  |   | Addr  | 
  +-------+  +-------+  +-------+  +-------+  +-------+   +-------+ 
 
 

Ŭ·¡½º´Â ´ÙÀ½°ú °°Àº ±â´ÉÀ» Á¦°øÇÑ´Ù.
  • ACE_Addr Ŭ·¡½º´Â ACE Network addressing °èÃþÀÇ ÃÖ»óÀ§¿¡ Á¸ÀçÇÑ´Ù.
  • ACE_INET_Addr Àº TCP(12)/IP(12)¿Í UDP(12)/IP addressing Á¤º¸¸¦ ó¸®ÇÑ´Ù. ÀÌ Å¬·¡½º´Â addressing Çϸ鼭 ¹ß»ýÇÒ ¼ö ÀÖ´Â ¸¹Àº ¹Ì¹¦ÇÑ ¹®Á¦µéÀ» Á¦°ÅÇÏ¿´´Ù.
             +--------------------------------------------------+ 
             | ACE_ADDR                                         | 
             |--------------------------------------------------| 
             | + sp_any : ACE_Addr                              | 
             | # addr_type_ : int                               | 
             | # addr_size_ : int                               | 
             |--------------------------------------------------| 
             | + ACE_Addr (type : int = -1, size : int = -1)    | 
             | + operator == (sap : const ACE_Addr&) : int      | 
             | + operator != (sap : const ACE_Addr&) : int      | 
             | + hash() : int                                   | 
             +--------------------------------------------------+ 
                                      ^ 
                                      | 
                                      | 
   +----------------------------------------------------------------------+ 
   | ACE_INET_Addr                                                        | 
   |----------------------------------------------------------------------| 
   | - inet_addr_ : sockaddr_in                                           | 
   |----------------------------------------------------------------------| 
   | + ACE_INET_Addr (port:unsigned short, host : const char *)           | 
   | + set (port:unsigned short, host:const char *) : int                 | 
   | + string_to_addr (address:const char *) : int                        | 
   | + addr_to_string (s : char *, max : size_t, ipfmt: int = 1) : int    | 
   | + get_port_number () : u_short                                       | 
   | + get_host_name (buff : char *, max : size_t) : int                  | 
   +----------------------------------------------------------------------+ 
 

9.10 ACE I/O Handle Class

Àú¼öÁØÀÇ C ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ÀÔÃâ·ÂÀ» ´Ù·ç´Â °ÍÀº ¹Ýµå½Ã ÇÊ¿äÇÑ ÀÛ¾÷ÀÌÀÚ °¡Àå ºó¹øÈ÷ ¹ß»ýÇÏ´Â ÀÛ¾÷ÀÌ´Ù. À¯´Ð½º ÇÁ·Î±×·¥Àº "ÆÄÀÏ ¿©´Â °Í¿¡¼­ ½ÃÀÛÇØ¼­", "ÆÄÀÏ ´Ý´Â °ÍÀ¸·Î ³¡³­´Ù" ¶ó°í ¸»Çصµ °úÇÔÀÌ ¾ø´Ù.

±×·¯³ª ¾ÈŸ±õ°Ôµµ Àú¼öÁØÀÇ CÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ÆÄÀÏÀÇ ÀÔÃâ·ÂÀ» ´Ù·ç´Â °ÍÀº Â¥Áõ³ª°íµµ ÈûµçÀÏÀÌ´Ù - ¾î·Á¿î ÀÏÀÌ ¾Æ´Ï´Ù. Â¥Áõ³ª°í Èûµé »ÓÀÌ´Ù -. ¾Æ·¡ÀÇ Äڵ带 È®ÀÎÇϱ⠹ٶõ´Ù.
int buggy_echo_server(u_short port_num) 
{ 
    sockaddr_in s_addr; 
 
    // À©µµ¿ìÁî ȯ°æ¿¡¼­´Â ÆÄÀÏÁö½ÃÀÚ·Î int¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù. 
    int acceptor = socket(PF_UNIX, SOCK_DGRAM, 0); 
 
    s_addr.sin_family = AF_INET; 
    s_addr.sin_port = port_num; 
    s_addr.sin_addr.s_addr = INADDR_ANY; 
    bind (acceptor, (sockaddr *)&s_addr, sizeof s_addr); 
    int handle = accept (acceptor, 0,0 ); 
    for (;;) 
    { 
        char buf[BUFSIZ]; 
        // À߸øµÈ ÆÄÀÏÁö½ÃÀÚ·Î ºÎÅÍ ÀоîµéÀ̰í ÀÖ´Ù. 
        ssize_t n = read (acceptor, buf, sizeof(buf)); 
        if (n <= 0) break; 
            write(handle, buf, n); 
    } 
} 
 

ACE¿¡¼­ Á¦°øÇϴ Ŭ·¡½º´Â À§ÀÇ ¹®Á¦µéÀ» ÇØ°áÇϰí ÀÖ´Ù.
  • ACE_IPC_SAP ´Â IPC wrapper facades Ŭ·¡½º °èÃþÀÇ ÃÖ»óÀ§¿¡ À§Ä¡ÇÑ´Ù. ÀÌ Å¬·¡½º´Â I/O¸¦ Á¦¾îÇϱâ À§ÇÑ ´Ù¸¥ ±âº»ÀûÀÎ ±â´ÉµéÀ» Á¦°øÇÑ´Ù.
  • ACE_SOCK ´Â ACE Socket wrapper facades Ŭ·¡½º °èÃþÀÇ ÃÖ»óÀ§¿¡ À§Ä¡ÇÑ´Ù.
    1. ¼ÒÄÏÀ» »ý¼ºÇϰųª ´Ý´Â´Ù.
    2. ·ÎÄà ȤÀº ¿ø°ÝÁöÀÇ ÁÖ¼Ò¸¦ ¾ò´Â´Ù.
    3. ¼ÒÄÏ Å¥ÀÇ Å©±âµîÀ» º¯°æÇϰųª ¾ò±â À§ÇÑ ¼ÒÄϿɼÇÀ» Á¦¾îÇÑ´Ù.
    4. boradcast(12)/multicast(12) Åë½Å°ú °ü·ÃµÈ Á¦¾î
    5. Nagle's ¾Ë°í¸®ÁòÀÇ Á¦¾î
           +-----------------------------+ 
           | ACE_IPC_SAP                 | 
           +-----------------------------+ 
           | - handle_ : ACE_HANDLE      | 
           +-----------------------------+ 
           | + enable(value : int)       | 
           | + disable(value : int)      | 
           | + get_handle() : ACE_HANDLE | 
           | + set_handle (h:ACE_HANDLE) | 
           +-----------------------------+ 
                          ^ 
                          |  
                          |  
  +----------------------------------------------------+ 
  | ACE_SOCK                                           | 
  +----------------------------------------------------+ 
  +----------------------------------------------------+ 
  | + open (type : int, proto_family: int,             | 
  |         protocol : int, reuse_addr : int) : int    | 
  | + close () : int                                   | 
  | + get_option (level : int, optins : int,           | 
  |            optval : void *, optlen : int *): int   | 
  | + set_option (level : int, options : int,          | 
  |            optval : void *, optlen : int) : int    | 
  | + get_local_addr (addr : ACE_Addr &) : int         | 
  | + get_remote_addr (addr : ACE_Addr &) : int        | 
  +----------------------------------------------------+ 
 

9.11 ACE_SOCK_Connector Ŭ·¡½º

¼ÒÄÏÀº µ¥ÀÌÅÍ Åë½ÅÀ» À§ÇÑ recv() ȤÀº send() ÇÔ¼ö¸¦ »ç¿ëÇϱâ Àü¿¡ ¿¬°áÇÏ´Â °úÁ¤À» °ÅÄ£´Ù(¾ðÁ¦³ª ±×·±°Ç ¾Æ´ÏÁö¸¸). ÀÌ Å¬·¡½º´Â Åë½Å ¿¬°á°ú °ü·ÃµÈ ±â´ÉµéÀ» Á¦°øÇÑ´Ù.

C¿¡¼­ Á¦°øÇÏ´Â ¼ÒÄÏ ÇÔ¼ö¸¦ »ç¿ëÇÒ °æ¿ì ´ÙÀ½°ú °°Àº °úÁ¤À» °ÅÄ¥°Çµ¥, ¸¸Àº ¹®Á¦Á¡À» °¡Áö°í ÀÖÀ½À» ¾Ë ¼ö ÀÖ´Ù.
int buggy_echo_client (u_short port_num, const char *s) 
{ 
    int handle = socket(PF_UNIX, SOCK_DGRAM, 0); 
 
    write(handle, s, strlen (s) + 1);     // ÇÔ¼öÀÇ À§Ä¡°¡ À߸ø µÇ¾ú´Ù.  
 
    sockaddr_in s_addr;     
    memset(&s_addr, 0, sizeof s_addr); 
    s_addr.sin_family = AF_INET; 
    s_addr.sin_port = htons(port_num);     
    connect(handle, (sockaddr *)&s_addr, sizeof s_addr); 
} 
 

ACE_Sock_Connector Ŭ·¡½º´Â Åë½ÅÀ» À§ÇÑ »õ·Î¿î Á¢Á¡(endpoint)¸¦ »ý¼ºÇÏ´Â ÀÏÀ» Çϸç, À§ÀÇ ¹®Á¦µéÀ» ÇØ°áÇϰí ÀÖ´Ù.
  • ¿¬°áÀ» ¿äûÇÏ°í ¿¬°áÀÌ ¼º°øÀûÀ¸·Î »ý¼ºµÇ¾úÀ» °æ¿ì µ¥ÀÌÅÍ Åë½ÅÀ» À§ÇØ »ç¿ëÇÒ ACE_SOCK_Stream À» ÃʱâÈ­ ÇÑ´Ù.
  • blocking, nonblocking¸¦ °áÁ¤Çϸç, ŸÀӾƿôÀ» Á¦¾îÇÑ´Ù.
                +-----------------+      +----------------+ 
                | ACE_SOCK_Stream |      | ACE_INET_Addr  | 
                +-----------------+      +----------------+ 
                        ^                        ^ 
                        |                        | 
                +-----------------\      +----------------\ 
                | PEER_STREAM     |      | PEER_ADDR      |  
                +-----------------+      +----------------+ 
                        |                        | 
   +---------------------------------------------------------------------+ 
   | ACE_SOCK_Connector                                                  | 
   +---------------------------------------------------------------------+ 
   +---------------------------------------------------------------------+ 
   | + connect (stream : ACE_SOCK_Stream&, remote_addr : ACE_Addr &,     | 
   |            timeout : ACE_Time_Value *= 0) : int                     | 
   | + complete (stream : ACE_SOCK_Stream&, remote_addr : ACE_Addr *=0,  | 
   |            timeout : ACE_Time_Value *= 0) : int                     | 
   +---------------------------------------------------------------------+ 
 

9.12 ACE Wrapper Facades ÀÇ Æ¯Â¡

  • ACE uses the C++ generic programming idiom to define & combine a set of characteristics to alter the behavior of a template class
  • In C++, the typedef & typename language feature is used to define a trait
    1. A trait provides a convenient way to associate related types, values, & functions with template parameter type without requiring that they be defined as members of the type
    2. Traits are used extensively in the C++ Standard Template Library (STL)

  • ACE Socket wrapper facades use traits to define the following associations
    1. PEER_ADDR : this trait defines the ACE_INET_Addr class associated with the ACE Socket Wrapper Facade
    2. PEER_STREAM : this trait defines the ACE_SOCK_Stream data transfer class associated with the ACE_SOCK_Acceptor & ACE_SOCK_Connector factories
class ACE_SOCK_Connector { 
public: 
  typedef ACE_INET_Addr  
          PEER_ADDR; 
  typedef ACE_SOCK_Stream  
          PEER_STREAM; 
  // ... 
 
} 
 
class ACE_TLI_Connector { 
public: 
  typedef ACE_INET_Addr  
          PEER_ADDR; 
  typedef ACE_TLI_Stream  
          PEER_STREAM; 
  // ... 
 
} 
 

9.13 ACE_SOCK_Connector ÀÌ¿ëÇϱâ

À¥¼­¹ö¿¡ ¿¬°áÇϴ Ŭ¶óÀÌ¾ðÆ® ¾ÖÇø®ÄÉÀ̼ÇÀÇ ¿¹Á¦¸¦ ÅëÇØ¼­ ACE_SOCK_ConnectorÀÇ »ç¿ë¹æ¹ý¿¡ ´ëÇØ¼­ ¼Ò°³ÇÑ´Ù.
int main(int argc, char **argv) 
{ 
    const char *pathname = argc > 1 ? argv[1] : "index.html"; 
    const char *server_hostname = argc > 2 ? argv[2] : "www.joinc.co.kr"; 
 
    typedef ACE_SOCK_Connector CONNECTOR; 
    CONNECTOR connector; 
     
    typename CONNECTOR::PEER_STREAM peer; 
    typename CONNECTOR::PEER_ADDR peer_addr; 
 
    if (peer_addr.set (80, server_hostname) == -1) 
        return 1; 
 
    // blocking ¸ðµå 
    else if (connector.connect (peer, peer_addr) == -1) 
        return 1; 
 
    // nonblocking ¸ðµå 
    if (connector.connect(peer, peer_addr, &ACE_TIME_Value::zero) == -1) 
    { 
        if(errno = EWOULDBLOCK) 
        { 
        } 
    } 
    if (connector.complete (peer, 0, &ACE_TIME_Value::zero) == -1) 
    { 
        // ¿¡·¯Ã³¸®  
    } 
 
    // ¿¬°á¿¡ Timeout¸¦ ¼³Á¤ÇÑ´Ù. 
    ACE_Time_Value timeout (5);    // 5ÃÊÀÇ Å¸ÀӾƿô 
    if (connector.connect (peer, peer_addr, &timeout) == -1 
    { 
        if (errno == ETIME) 
        { 
            // ¿¡·¯Ã³¸® 
        } 
    } 
} 
 

ACE_SOCK_Connector ÀԷµǴ ACE_Time_Value¿¡ µû¶ó¼­ ´ÙÀ½°ú °°Àº ÇൿÀ» ÇÑ´Ù.
°ª ¼³¸í
NULL Pointer ¿¬°áÀÌ ÀÌ·ç¾îÁú ¶§±îÁö ¹«ÇÑÁ¤ ±â´Ù¸°´Ù.
Non-NULL À̰í sec()¿Í usec()°¡ 0Àϰæ¿ì nonblocking ¿¬°áÀ» ½ÃµµÇÑ´Ù. |
Non-NULLÀ̰í sec()¶Ç´Â usec()°¡ 0º¸´Ù Ŭ °æ¿ì ÇØ´ç ½Ã°£µ¿¾È ¿¬°áÀÌ µÇ±â¸¦ ±â´Ù¸°´Ù. ÁÖ¾îÁø ½Ã°£µ¿¾È ¿¬°áÀÌ µÇÁö ¾Ê´Â´Ù¸é -1À» ¸®ÅÏÇϰí errno·Î ETIMEÀ» ¼³Á¤ÇÑ´Ù.

9.14 ACE_SOCK_Stream Ŭ·¡½º

°³¹ßÀÚ°¡ ¼ÒÄÏÀ» À߸ø ÀÌ¿ëÇÏ´õ¶óµµ º¸ÅëÀÇ °æ¿ì ÄÄÆÄÀÏ °úÁ¤¿¡¼­ ¿¡·¯°¡ ¹ß»ýÇÏÁö ¾Ê´Â´Ù. À̰ÍÀº ÇÁ·Î±×·¥¿¡ ½É°¢ÇÑ ¹®Á¦¸¦ ¹ß»ý½Ãų ¼ö ÀÖ´Ù.
int buggy_echo_server(u_short port_num) 
{ 
    sockaddr_in s_addr; 
    int acceptor = sock(PF_UNIX, SOCK_DGRAM, 0); 
    s_addr.sin_family = AF_INET; 
    s_addr.sin_port = port_num; 
    s_addr.sin_addr.s_addr = INADDR_ANY; 
    bind(acceptor, (sockaddr *)&s_addr, sizeof(s_addr0); 
    int handle = accept(acceptor, 0, 0); 
    for (;;) 
    { 
        char buf[BUFSIZ]; 
         
        // À߸øµÈ ÆÄÀÏÁö½ÃÀÚ·Î ºÎÅÍ Àаí ÀÖ´Ù. 
        ssize_t n = read(acceptor, buf, sizeof(buf)); 
        if(n <= 0) break; 
        write(handle, buf, n); 
    } 
} 
 

ACE_SOCK_StreamÀº statically type-checked ÀÎÅÍÆäÀ̽º¸¦ ÀÌ¿ëÇÏ°Ô ÇÔÀ¸·Î½á µ¥ÀÌÅÍ ±³È¯¿¡ À־ À߸øµÈ µ¥ÀÌÅÍ ÀÔ·ÂÀÚü¸¦ ÇÏÁö ¸øÇϵµ·Ï Çϰí ÀÖ´Ù.

ACE_SOCK_Stream Ŭ·¡½º´Â ´ÙÀ½°ú °°Àº ±â´ÉÀ» Á¦°øÇÑ´Ù.
  • ¼ÒÄÏ¿¡¼­ ¹ß»ýÇÏ´Â µ¥ÀÌÅÍ Àü´Þ°úÁ¤À» ĸ½¶È­ ÇÑ´Ù.
  • Á¤È®ÇÑ n byte Åë½ÅÀ» Áö¿øÇÑ´Ù.
  • blocking, nonblocking ¹× ŸÀӾƿôÀ» Áö¿øÇÑ´Ù.
  • ÇϳªÀÇ ¿¬¼ÓµÈ ¹öÆÛ¸¦ »ç¿ëÇÏÁö ¾Ê°í È£Ãâ´ç ¹öÆÛ¸¦ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï Áö¿øÇÑ´Ù.
  • Support for ``gather-write'' operations, which transmit the contents of multiple noncontiguous data buffers in a single operation
  • Support for generic programming techniques that enable the wholesale replacement of functionality via C++ parameterized types
 +---------------+         +------------------------------------------------+ 
 | ACE_SOCK      |<--------| ACE_SOCK_IO                                    | 
 +---------------+         +------------------------------------------------+ 
                           | + recv (buf : void *, n : size_t               | 
 +---------------+         |         timeout : ACE_Time_Value * = 0) : int  | 
 | ACE_INET_Addr |         | + send (buf : void *, n : size_t,              | 
 +---------------+         |         timeout : ACE_Time_Value * = 0) : int  | 
        ^                  +------------------------------------------------+ 
        |                            ^ 
 +---------------\                   | 
 | PEER_ADDR     |                   | 
 +---------------+                   | 
                                     | 
 +-----------------------------------------------------------------------+ 
 | ACE_SOCK_Stream                                                       | 
 +-----------------------------------------------------------------------+ 
 +-----------------------------------------------------------------------+ 
 | + recv_n (buf : void *, len : size_t, timeout : ACE_Time_Value * = 0, | 
 |           bytes_recvd : size_t * = 0) : ssize_t                       | 
 | + send_n (buf : void *, len : size_t, timeout : ACE_Time_Value * = 0, | 
 |           bytes_recvd : size_t * = 0) : ssize_t                       | 
 | + send_n (mblk : ACE_Message_Block *, timeout : ACE_Time_Value * = 0, | 
 |           bytes_send : size_t * = 0) : ssize_t                        | 
 | + recvv_n (v : iovec[], cnt : size_t, timeout : ACE_Time_Value * = 0, | 
 |           bytes_recvd : size_t * = 0) : ssize_t                       | 
 | + sendv_n (v : iovec[], cnt : size_t, timeout : ACE_Time_Value * = 0, | 
 |           bytes_recvd : size_t * = 0) : ssize_t                       | 
 +-----------------------------------------------------------------------+ 
 

´ÙÀ½Àº ACE_SOCK_StreamÀ» ÀÌ¿ëÇØ¼­ À¥¼­¹ö·Î ºÎÅÍ µ¥ÀÌÅ͸¦ ÁÖ°í ¹Þ´Â ÇÁ·Î±×·¥ ¿¹Á¦ÀÌ´Ù.
// ACE_SOCK_Connector¸¦ ÅëÇØ¼­ ¿¬°áÀÌ µÈ»óÅ¿¡¼­ ºÎÅÍ ½ÃÀÛÇÑ´Ù. 
char buf[BUFSIZ]; 
iovec iov[3]; 
iov[0].iov_base = (char *)"GET"; 
iov[0].iov_len = 4;    // "GET"ÀÇ ±æÀÌ 
iov[1].iov_base = (char *)pathname; 
iov[1].iov_len = strlen(pathname); 
iov[2].iov_bas = (char *)"HTTP/1.0\n\n"; 
iov[2].iov_len = 13;   // "HTTP/1.0\n\n"ÀÇ ±æÀÌ 
 
// blocking ¸ðµå·Î ACE_SOCK_Stream¿¡ ¾²±â 
if (peer.sendv_n (iov, 3) == -1) 
    return 1; 
 
// blocking ¸ðµå·Î ACE_SOCK_StreamÀ¸·Î ºÎÅÍ Àбâ 
for (ssize_t n; (n = peer.recv(buf, sizeof(buf)) > 0;) 
    ACE::write_n (ACE_STDOUT, buf, n); 
return peer.close() == -1 ? 1 : 0; 
 
  • enable(), disable() ¸Þ¼­µå¸¦ ÅëÇÑ blocking¹× nonblocking Á¦¾î
    • peer.enable(ACE_NONBLOCK); // nonblocking Ȱ¼ºÈ­
    • peer.disable(ACE_NONBLOCK); // nonblocking ºñ Ȱ¼ºÈ­
  • ŸÀӾƿô ¼³Á¤

    ACE_Time_Value timeout (10); 
    if (peer.sendv_n (iov, 3, &timeout) == -1) 
    { 
        // ¿¡·¯Ã³¸® 
    } 
     

9.15 Nagle(12) ¾Ë°í¸®Áò Á¦¾î

[[Include(Term_Nagle)]]

ACE´Â °£´ÜÇÏ°Ô Nagle ¾Ë°í¸®ÁòÀ» Ȱ¼ºÈ­½ÃŰ°Å³ª ºñȰ¼ºÈ­ ½Ãų ¼ö ÀÖ´Ù.
peer.enable(TCP_NODELAY);    // Nagle ¾Ë°í¸®Áò ºñȰ¼ºÈ­ 
peer.disable(TCP_NODELAY);   // Nagle ¾Ë°í¸®Áò Ȱ¼ºÈ­ 
 

9.16 ACE_SOCK_Acceptor Ŭ·¡½º

C¿¡¼­ Á¦°øÇÏ´Â Àú¼öÁØÀÇ Socket API(12)¸¦ »ç¿ëÇÒ °æ¿ì °³¹ßÀÚ´Â ¿©·¯°¡Áö ¿øÀÎÀ¸·Î À߸øµÈ Äڵ带 »ý¼ºÇÒ ¼ö ÀÖ´Ù. ´õ Å«¹®Á¦´Â ÀÌ·¯ÇÑ À߸øµÈ ÄÚµåµéÀÌ ¹®Á¦¾øÀÌ ÄÄÆÄÀÏ µÈ´Ù´Â Á¡ÀÌ´Ù. ACE_SOCK_Acceptor Ŭ·¡½º´Â ÀÌ·¯ÇÑ ¹®Á¦¸¦ ÇØ°áÇϰí ÀÖ´Ù.
int buggy_echo_server (u_short port_num)  
{  
    sockaddr_in s_addr; 
    int acceptor = socket (PF_UNIX, SOCK_DGRAM, 0); 
    s_addr.sin_family = AF_INET; 
    s_addr.sin_port = port_num; 
    s_addr.sin_addr.s_addr = INADDR_ANY; 
    bind (acceptor, (sockaddr *) &s_addr, sizeof s_addr); 
    int handle = accept (acceptor, 0, 0); 
    for (;;)  
    { 
        char buf[BUFSIZ]; 
 
        // À߸øµÈ ¼ÒÄÏ Áö½ÃÀÚ·Î ºÎÅÍ ÀоîµéÀ̰í ÀÖ´Ù. 
        ssize_t n = read (acceptor, buf, sizeof buf); 
        if (n <= 0) break; 
        write (handle, buf, n); 
    } 
} 
 

ACE_SOCK_Acceptor Ŭ·¡½º´Â À§ÀÇ ¹®Á¦¸¦ ÇØ°áÇÒ ¼ö ÀÖ´Â ´ÙÀ½°ú °°Àº ±â´ÉµéÀ» Á¦°øÇÑ´Ù.

  • ¿ø°ÝÁöÀÇ connector·Î ºÎÅÍ ¿¬°áÀ» ±â´Ù¸®°í, ¿¬°áÀÌ ¸Î¾îÁö¸é ACE_SOCK_Stream °´Ã¼¸¦ ÃʱâÈ­ ÇÑ´Ù.
  • blocking ȤÀº nonblocking »óÅ·Π¿¬°áÀ» ±â´Ù¸± ¼ö ÀÖÀ¸¸ç, ŸÀӾƿôÀ» °Ë»çÇÒ ¼öµµ ÀÖ´Ù.
  • generic ÇÁ·Î±×·¡¹Ö ±â¼úÀ» Áö¿øÇÑ´Ù.
   +---------------+    +---------------+    +-----------------+ 
   | ACE_INET_Addr |    | ACE_SOCK      |    | ACE_SOCK_Stream | 
   +---------------+    +---------------+    +-----------------+ 
          ^                    ^                    ^ 
          |                    |                    |  
   +---------------+           |             +---------------+ 
   | PEER_ADDR     |           |             | PEER_STREAM   | 
   +---------------+           |             +---------------+ 
          |                    |                    | 
   +-----------------------------------------------------------+ 
   | ACE_SOCK_Acceptor                                         | 
   +-----------------------------------------------------------+ 
   +-----------------------------------------------------------+ 
   | + open (local_addr : ACE_Addr &): int                     | 
   | + accept (stream : ACE_SOCK_Stream &) : int               | 
   +-----------------------------------------------------------+ 
 

9.17 ACE_SOCK_Acceptor Ŭ·¡½º¸¦ »ç¿ëÇÏÀÚ

¾Æ·¡ÀÇ ÄÚµå´Â ACE_SOCK_Acceptor °ú ACE_SOCK_StreamÀ» ÀÌ¿ëÇØ¼­ ¸¸µé¾îÁø ¿¹Á¦ÀÌ´Ù. À¥Å¬¶óÀÌ¾ðÆ®·Î ºÎÅÍ ¿¬°áÀ» ±â´Ù¸®°í µ¥ÀÌÅ͸¦ ÁÖ°í¹Þ´Â À¥¼­¹ö·Î½áÀÇ ¿ªÇÒÀ» ÇÏ´Â ÇÁ·Î±×·¥ÀÌ´Ù.
extern char *get_url_pathname (ACE_SOCK_Stream *); 
int main() 
{ 
    ACE_INET_Addr server_addr; 
    ACE_SOCK_Acceptor acceptor; 
    ACE_SOCK_Stream peer; 
 
    if (server_addr.set(80) == -1) return 1; 
    if (acceptor.open(server_addr) == -1) return 1; 
 
    for (;;) 
    { 
        if (acceptor.accept(peer) == -1) return 1; 
        peer.disable (ACE_NONBLOCK); 
 
        ACE_Auto_Array_Ptr<char *> pathname (get_url_pathname (peer)); 
        ACE_Mem_Map mapped_file (pathname.get()); 
 
        if (peer.send_n (mapped_file.addr(), 
                        mapped_file.size()) == -1) return 1; 
        peer.close();     
    } 
    return acceptor.close() == -1 ? 1: 0; 
} 
 

9.18 ACE_Mem_Map Ŭ·¡½º

¸¹Àº Çö´ëÀûÀÎ ¿î¿µÃ¼Á¦ÀÇ ´ëºÎºÐÀº ÇÁ·Î¼¼½ºÀÇ °¡»ó¸Þ¸ð¸® ¿µ¿ªÀ» ÆÄÀÏ¿¡ ´ëÀÀ ½Ãų ¼ö ÀÖ´Â Memory Map ±â¼úÀ» Á¦°øÇϰí ÀÖ´Ù. mmap À§Å°¸¦ Âü°íÇϱ⠹ٶõ´Ù.

Memory-mapped ÆÄÀÏÀº °¡»ó¸Þ¸ð¸® ¿µ¿ªÀÇ µ¥ÀÌÅ͸¦ ÆÄÀÏ¿¡ ´ëÀÀ½ÃÅ´À¸·Î½á (´Ù¸¥ ÇÁ·Î¼¼½º¶ó°í ÇÒÁö¶óµµ)Á÷Á¢ Àаųª ¾µ¼ö ÀÖ°Ô µµ¿ÍÁØ´Ù. ÀÌ·¯ÇÑ Æ¯¼ºÀº IPC(12)¿ëµµ·Î »ç¿ë°¡´ÉÇϸç, ¶§¶§·Î ¸Þ¸ð¸®³»¿ëÀ» (ÆÄÀÏ¿¡ ³²±â ¶§¹®¿¡)¹é¾÷Çϱâ À§Çѿ뵵·Îµµ »ç¿ëÇÒ ¼ö ÀÖ°Ô ÇÑ´Ù.

¸Þ¸ð¸®¸ÊÀº ¿î¿µÃ¼Á¦¸¶´Ù ¼­·Î ´Ù¸¥ ¹æ½ÄÀ¸·Î ÀÛµ¿Çϴµ¥, ACE´Â À̵éÀ» ĸ½¶È­½ÃÄѼ­ °³¹ßÀÚ°¡ °í¹Î¾øÀÌ »ç¿ëÇϵµ·Ï µµ¿ÍÁØ´Ù. ACE´Â ACE_Mem_Map Ŭ·¡½º¸¦ Á¦°øÇÑ´Ù.

9.19 ACE_Message_Block Ŭ·¡½º

Àü´ÞÇϰíÀÚ ÇÏ´Â                                                                        󸮸¦ À§ÇØ ±â´Ù¸®°íÀÖ´Â 
¸Þ½ÃÁö ¹öÆÛ                                                                            ¸Þ½ÃÁö ¹öÆÛ 
 +----+     +-------------------+   +----+          +----+     +-------------------+     +----+ 
 |++++|     | SOCK_Connector    |   |++++|          |++++|     | SOCK_Acceptor     |     |++++| 
 +----+     | SOCK_Stream       |   +----+          +----+     | SOCK_Stream       |     +----+ 
   |        | connect()     ----|------------------------------|>accept()          |       |    
 +----+     | send() / recv()   |                              | send()/recv()     |     +----+ 
 |++++|     | close()           |                              | close()           |     |++++| 
 +----+     +-------------------+                              +-------------------+     +----+ 
   |                                                                                       | 
 +----+                                                                                  +----+ 
 |++++|                                                                                  |++++| 
 +----+                                                                                  +----+ 
 
³×Æ®¿öÅ© ¾ÖÇø®ÄÉÀ̼ǿ¡¼­ÀÇ ÇÙ½ÉÀº °á±¹ ¿äû°ú ÀÀ´äÀ̰í, ¿äû°ú ÀÀ´äÀº ¸Þ½ÃÁö¸¦ ÁÖ°í ¹ÞÀ½À¸·Î½á ÀÌ·ç¾îÁø´Ù´Â Á¡¿¡¼­ ¸Þ½ÃÁö¸¦ ¾î¶»°Ô È¿°úÀûÀ¸·Î Àß Ã³¸®ÇÏ´À³Ä°¡ °¡Àå Áß¿äÇÑ ÇÙ½ÉÀ̶ó°í ÇÒ ¼ö ÀÖ´Ù. ¸Þ½ÃÁö¸¦ Á¦´ë·Î ó¸®Çϱâ À§Çؼ­´Â ´ÙÀ½°ú °°Àº »çÇ×µéÀÌ ÃæÁ·µÇ¾î¾ß ÇÑ´Ù.
  1. ³×Æ®¿öÅ© ¾ÖÇø®ÄÉÀ̼ÇÀ» ÀÛ¼ºÇÏ°Ô µÇ¸é ÀÀ¿ë ¼öÁØÀÇ ÇÁ·ÎÅäÄݵéÀ» Á¤ÀÇ ÇÑ´Ù. ±×·¯±â À§Çؼ­´Â ¸Þ½ÃÁö¿¡¼­ Çì´õ,µ¥ÀÌÅ͵îÀ» ºÐ¸®ÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù.
  2. MTU(12)µî¿¡ ÀÇÇØ¼­ ¸Þ½ÃÁö´Â ºÐ¸®µÇ°Å³ª ȤÀº ºÙ¾î¼­ µé¾î¿Ã ¼ö ÀÖ´Ù. À̰æ¿ì ´ÜÀ§ ¸Þ½ÃÁö·Î ¸¸µé±â À§ÇÑ ·çƾÀÌ ÇÊ¿äÇÏ°Ô µÈ´Ù.
  3. ¹Þ¾ÆµéÀÎ ¸Þ½ÃÁö´Â ´Ù¸¥ ÇÁ·Î¼¼½º³ª ¾²·¹µå·Î ³Ñ±â±â À§Çؼ­ ¹öÆÛÇüÅ·Π°ü¸® µÉ ¼ö ÀÖ¾î¾ß ÇÑ´Ù.

ACE_Message_Block Ŭ·¡½º´Â ¸Þ½ÃÁö¸¦ È¿°úÀûÀ¸·Î ó¸®Çϵµ·Ï ´ÙÀ½°ú °°Àº ±â´ÉµéÀ» Á¦°øÇÑ´Ù.
  1. °¢°¢ÀÇ ACE_Message_Block´Â ½ÇÁ¦ ´Ù·ç¾î¾ßÇÒ µ¥ÀÌÅ͸¦ Æ÷ÇÔÇϰí ÀÖ´Â ACE_Data_Block¿¡ ´ëÇÑ Æ÷ÀÎÆ® Á¤º¸¸¦ °¡Áö°í ÀÖ´Ù.
  2. ´ÙÁßÀÇ ¸Þ½ÃÁö¸¦ chain ÇüÅ·Π°ü¸®ÇÒ ¼ö ÀÖ´Ù.
  3. ´ÙÁßÀÇ ¸Þ½ÃÁö¸¦ ACE_Message_Queue¸¦ ÅëÇØ¼­ µ¿½Ã °ü¸® °¡´ÉÇÏ´Ù.
  4. ÀÚµ¿À¸·Î µ¿±âÈ­¿Í ¸Þ¸ð¸® °ü¸®°¡ ÀÌ·ç¾îÁø´Ù.
 +-----------------------------------------------+ 
 | ACE_Message_Block                             | 
 +-----------------------------------------------+ 
 | # rd_ptr_ : size_t                            | 
 | # wr_ptr_ : size_t                            | 
 | # cont_ : ACE_Message_Block *                 | 
 | # next_ : ACE_Message_Block *                 | 
 | # prev_ : ACE_Message_Block *                 | 
 | # data_block_ : ACE_Data_Block *              | 
 | + init (size: size_t) : int                   | 
 | + msg_type (type : ACE_Message_Type)          |            +------------------+ 
 | + msg_type () : ACE_message_Type              |            | ACE_Data_Block   | 
 | + msg_priority (prio : u_long)                |<>--------> +------------------+ 
 | + clone () : ACE_Message_Block *              |*         1 | # base_ : char * | 
 | + duplicate () : ACE_Message_Block *          |            | # refcnt_ : int  | 
 | + release () : ACE_Message_Block *            |            +------------------+ 
 | + set_flags (flags : u_long) : u_long         |            +------------------+ 
 | + clr_flags (flags : u_long) : u_long         | 
 | + copy (buf : const char *, n : size_t) : int | 
 | + rd_ptr (n : size_t)                         | 
 | + rd_ptr () : char *                          | 
 | + wr_ptr (n : size_t)                         | 
 | + wr_ptr () : char *                          | 
 | + length () : size_t                          | 
 | + total_length () : size_t                    | 
 | + size () : size_t                            | 
 +-----------------------------------------------+ 
 
9.19.1 2Á¾·ùÀÇ ACE_Message_Block Ŭ·¡½º
°£´ÜÇÑ ¸Þ½ÃÁö¿Í(Simple Message Structure) ¿©·¯ÇüÅÂÀÇ ¸Þ½ÃÁö¸¦ Æ÷ÇÔÇÑ (Composite message contain) ÇüŸ¦ ó¸®ÇÒ ¼ö ÀÖµµ·Ï Áö¿øµÇ°í ÀÖ´Ù.

ACE_Message_Block_Type.gif

°£´ÜÇÑ ¸Þ½ÃÁö¸¦ Áö¿øÇÏ´Â ACE_Message_Block´Â ÇϳªÀÇ ´ÜÀÏÇÑ Çü½ÄÀ» °¡Áö´Â µ¥ÀÌÅ͸¦ Æ÷ÀÎÆ®ÇÑ´Ù.

¹Ý¸é µÎ°³ÀÌ»óÀÇ ACE_Message_Block°¡ ¼­·Î´Ù¸¥ ÇüŸ¦ °¡Áö´Â µ¥ÀÌÅ͸¦ »ç¿ëÇØ¾ß ÇÏ´Â °æ¿ì°¡ ÀÖÀ» °ÍÀÌ´Ù. ÀÌ·¯ÇÑ °æ¿ì´Â ¿©·¯Á¾·ùÀÇ ¸Þ½ÃÁö¸¦ ó¸®ÇØ¾ß ÇÏ´Â ¹Ìµé¿þ¾î¸¦ ÀÛ¼ºÇϰíÀÚ ÇÒ°æ¿ì Á¾Á¾¹ß»ýÇÑ´Ù. ACE_Message_Block´Â ÀÌ·¯ÇÑ º¹ÀâÇÑ ÇüÅÂÀÇ µ¥ÀÌÅͱ¸Á¶¸¦ °ü¸®Çϵµ·Ï Áö¿øÇÑ´Ù.

9.20 ACE_Message_BlockÀÇ ÀÌ¿ë

´ÙÀ½Àº ACE_Message_Blocks¸¦ ÀÌ¿ëÇØ¼­ ¾î¶»°Ô µ¥ÀÌÅÍÀÇ ¸ñ·ÏÀ» ¸¸µé°í À¯ÁöÇÏ´ÂÁö¸¦ º¸¿©ÁØ´Ù.

int main (int argc, char *argv[]) 
{ 
  // BUFSIZÀÇ Å©±â¸¦ °¡Áö´Â ACE_Message_Block¸¦ »ý¼ºÇÑ´Ù. 
  ACE_Message_Block *head = new ACE_Message_Block (BUFSIZ); 
  ACE_Message_Block *mblk = head; 
 
  for (;;) { 
    // wr_ptr ()À» ÀÌ¿ëÇØ¼­ Ç¥ÁØÀÔ·ÂÀ¸·Î ºÎÅÍ ÀоîµéÀÎ µ¥ÀÌÅ͸¦  
    // ¾´´Ù. 
    ssize_t nbytes = ACE::read_n (ACE_STDIN,  
                                  mblk->wr_ptr (),  
                                  mblk->size ()); 
    if (nbytes <= 0) 
      break; // Break out at EOF or error. 
 
    // ÀоîµéÀÎ ¸Þ½ÃÁöÀÇ ³¡À» ¸íÈ®È÷ Çϱâ À§Çؼ­ Å©±â¸¦ ¸í½ÃÇÑ´Ù. 
    mblk->wr_ptr (nbytes);  
 
    mblk->cont (new ACE_Message_Block (BUFSIZ)); 
    mblk = mblk->cont (); 
  } 
 
  // Print the contents of the list to the standard output. 
  for (mblk = head; mblk != 0; mblk = mblk->cont ())  
    ACE::write_n (ACE_STDOUT, mblk->rd_ptr (), mblk->length ()); 
   
  head->release (); // Release all the memory in the chain. 
  return 0; 
} 
 

10 Client Application ÀÛ¼º

10.1 Logging Client

±×·³ ACE C++ Socket Wrapper facades¸¦ ÀÌ¿ëÇØ¼­ ÀÛ¼ºµÈ Ŭ¶óÀÌ¾ðÆ® ÇÁ·Î±×·¥ÀÇ ÇüÅ¿¡ ´ëÇØ¼­ ¾Ë¾Æº¸µµ·Ï ÇÑ´Ù.

class Logging_Client { 
public: 
  // Send <log_record> to the server. 
  int send (const ACE_Log_Record &log_record); 
  // Accessor method. 
  ACE_SOCK_Stream &peer () { return logging_peer_; } 
  // Close the connection to the server. 
  ~Logging_Client () { logging_peer_.close (); } 
private: 
  ACE_SOCK_Stream logging_peer_; // Connected to server. 
}; 
 

´ÙÀ½Àº Logging_Client::send() ¸Þ¼­µå¿¡ ´ëÇÑ ¼³¸íÀÌ´Ù.
  1. µ¥ÀÌÅÍÀÇ Å©±â¸¦ °è»êÇÑ´Ù. (2-8)
  2. µ¥ÀÌÅÍ¿¡¼­ Çì´õ¿Í bodyºÎºÐÀ» ºÐ¸®Çس½´Ù. (10-16)
  3. ºÐ¸®µÈ Á¤º¸´Â logging server ·Î º¸³½´Ù.(18-24)
 1 int Logging_Client::send (const ACE_Log_Record &log_record) { 
 2   const size_t max_payload_size = 
 3       4 // type() 
 4     + 8 // timestamp 
 5     + 4 // process id 
 6     + 4 // data length 
 7     + ACE_Log_Record::ACE_MAXLOGMSGLEN // data 
 8     + ACE_CDR::MAX_ALIGNMENT; // padding; 
 9  
10   ACE_OutputCDR payload (max_payload_size); 
11   payload << log_record; 
12   ACE_CDR::ULong length = payload.total_length (); 
13  
14   ACE_OutputCDR header (ACE_CDR::MAX_ALIGNMENT + 8); 
15   header << ACE_OutputCDR::from_boolean (ACE_CDR_BYTE_ORDER); 
16   header << ACE_CDR::ULong (length); 
17  
18   iovec iov[2]; 
19   iov[0].iov_base = header.begin ()->rd_ptr (); 
20   iov[0].iov_len  = 8; 
21   iov[1].iov_base = payload.begin ()->rd_ptr (); 
22   iov[1].iov_len  = length; 
23  
24   return logging_peer_.sendv_n (iov, 2); 
25 } 
 

´ÙÀ½Àº mainÇÔ¼ö´Ù.
 1 int main (int argc, char *argv[])  
 2 { 
 3   u_short logger_port = 
 4     argc > 1 ? atoi (argv[1]) : 0; 
 5   const char *logger_host = 
 6     argc > 2 ? argv[2] : ACE_DEFAULT_SERVER_HOST; 
 7   int result; 
 8  
 9   ACE_INET_Addr server_addr; 
10    
11   if (logger_port != 0) 
12     result = server_addr.set (logger_port, logger_host); 
13   else 
14     result = server_addr.set ("ace_logger", logger_host); 
15   if (result == -1)  
16     ACE_ERROR_RETURN((LM_ERROR, 
17                      "lookup %s, %p\n", 
18                      logger_port == 0 ? "ace_logger" : argv[1], 
19                      logger_host), 1); 
20 
21   ACE_SOCK_Connector connector; 
22   Logging_Client logging_client; 
23  
24   if (connector.connect (logging_client.peer (), 
25                          server_addr) < 0) 
26     ACE_ERROR_RETURN ((LM_ERROR, 
27                       "%p\n", 
28                       "connect()"), 
29                       1); 
30 
31   // Limit the number of characters read on each record. 
32   cin.width (ACE_Log_Record::MAXLOGMSGLEN); 
33   for (;;) { 
34     std::string user_input; 
35     getline (cin, user_input, '\n'); 
36  
37     if (!cin || cin.eof ()) break; 
38  
39     ACE_Time_Value now (ACE_OS::gettimeofday ()); 
40     ACE_Log_Record log_record (LM_INFO, now, 
41                                ACE_OS::getpid ()); 
42     log_record.msg_data (user_input.c_str ()); 
43  
44     if (logging_client.send (log_record) == -1) 
45       ACE_ERROR_RETURN ((LM_ERROR, 
46                          "%p\n", "logging_client.send()"), 1); 
47   } 
48  
49   return 0; // Logging_Client destructor  
50             // closes TCP connection. 
51 } 
 
 

11 Logging Server ÀÛ¼º

´ÙÀ½Àº ÀÛ¼ºÇÒ Logging_ServerÀÇ Å¬·¡½º °èÃþÀÌ´Ù. Logging_Handler class´Â °£´ÜÇÏ°Ô Á¤ÀÇ ÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù. °èÃþÀ» ÀÌ·ç°í ÀÖ´Â °¢°¢ÀÇ Å¬·¡½º´Â º°µµ·Î ¼³¸íÀ» Çϵµ·Ï ÇϰڴÙ.
 +----------------------------------------------------------------------+ 
 | Logging_Server                                                       |  
 +----------------------------------------------------------------------+ 
 | - acceptor_ : ACE_SOCK_Acceptor                                      |  
 +----------------------------------------------------------------------+ 
 | + run(argc, : int, argv : char **) : int                             | 
 | # open (port : w_short = 0) : int                                    | 
 | # wait_for_multiple_events () : int                                  | 
 | # handle_connections () : int                                        | 
 | # handle_data (s : ACE_SOCK_Stream *) : int                          | 
 | # make_log_file (f : ACE_FILE_IO&, s, ACE_SOCK_Stream *= 0): int     | 
 | # acceptor() : ACE_SOCK_Acceptor&                                    | 
 +----------------------------------------------------------------------+ 
                                 ^ 
                                 | 
       +------------------------------------------------------+ 
       |                |                 |                   | 
 +-----------+    +-----------+    +-------------+     +-------------+ 
 | Iterative |    | Reactive  |    | Process Per |     | Thread Per  | 
 | Logging   |    | Logging   |    | Connection  |     | Connection  | 
 | Server    |    | Server    |    | Logging     |     | Logging     | 
 +-----------+    +-----------+    | Server      |     | Server      | 
       |                |          +-------------+     +-------------+ 
       |                |                 |                |  ^ 
       |                |   +-------------+                |  | 
       |                |   |                              |  | 
       |        +-----------------+                        |  | 
       +------<>| Logging_Handler |<-----------------------+  | 
                +-----------------+                           | 
                                                        +---------------+ 
                                                        | RT Thread Per | 
                                                        | Connection    | 
                                                        | Logging       | 
                                                        | Server        | 
                                                        +---------------+ 
 

11.1 Logging Server ÄÚµå

ÀÌ ¿¹Á¦´Â ACE_Message_Block¿Í ACE CDR Ŭ·¡½º¸¦ ÀÌ¿ëÇØ¼­ ¸¸µç °£´ÜÇÑ ·Î±ë ¼­¹ö´Ù.

// Forward declaration. 
class ACE_SOCK_Stream; 
 
class Logging_Server 
{ 
public: 
  // Template Method that runs logging server's event loop. 
  virtual int run (int argc, char *argv[]); 
 
protected: 
  // The following four methods are ``hooks'' that can be 
  // overridden by subclasses.  
  virtual int open (u_short logger_port = 0); 
  virtual int wait_for_multiple_events () { return 0; } 
  virtual int handle_connections () = 0; 
  virtual int handle_data (ACE_SOCK_Stream * = 0) = 0; 
  // This helper method can be used by the hook methods. 
  int make_log_file (ACE_FILE_IO &, ACE_SOCK_Stream * = 0); 
 
  // Close the socket endpoint and shutdown ACE. 
  virtual ~Logging_Server () {  
    acceptor_.close ();  
  } 
 
  // Accessor. 
  ACE_SOCK_Acceptor &acceptor () {  
    return acceptor_;  
  } 
 
private: 
  // Socket acceptor endpoint.  
  ACE_SOCK_Acceptor acceptor_;  
}; 
 

#include "ace/FILE_Addr.h" 
#include "ace/FILE_Connector.h" 
#include "ace/FILE_IO.h" 
#include "ace/INET_Addr.h" 
#include "ace/SOCK_Stream.h" 
#include "Logging_Server.h" 
 
int Logging_Server::run (int argc, char *argv[]) 
{ 
  if (open (argc > 1 ? atoi (argv[1]) : 0) == -1) 
    return -1; 
 
  for (;;) { 
    if (wait_for_multiple_events () == -1) return -1; 
    if (handle_connections () == -1) return -1; 
    if (handle_data () == -1) return -1; 
  } 
  return 0; 
} 
int Logging_Server::open (u_short logger_port) 
{ 
  // Raises the number of available socket handles to  
  // the maximum supported by the OS platform. 
  ACE::set_handle_limit (); 
     
  ACE_INET_Addr server_addr; 
  int result; 
 
  if (logger_port != 0) 
    result = server_addr.set (logger_port, INADDR_ANY); 
  else 
    result = server_addr.set ("ace_logger", INADDR_ANY); 
  if (result == -1) return -1; 
 
  // Start listening and enable reuse of listen address  
  // for quick restarts. 
  return acceptor_.open (server_addr, 1); 
} 
int Logging_Server::make_log_file (ACE_FILE_IO &logging_file, 
                                   ACE_SOCK_Stream *logging_peer) 
{  
  std::string filename (MAXHOSTNAMELEN, ¡¯\0¡¯); 
 
  if (logging_peer != 0) { // Use client host name as file name. 
    ACE_INET_Addr logging_peer_addr; 
    logging_peer->get_remote_addr (logging_peer_addr); 
    logging_peer_addr.get_host_name (filename.c_str (),  
                                     filename.size ()); 
    filename += ".log"; 
  } else filename = "logging_server.log"; 
 
  ACE_FILE_Connector connector; 
  return connector.connect (logging_file,  
                            ACE_FILE_Addr (filename.c_str ()), 
                            0, // No time-out. 
                            ACE_Addr::sap_any, // Ignored. 
                            0, // Don't try to reuse the addr. 
                            O_RDWR|O_CREAT|O_APPEND, 
                            ACE_DEFAULT_FILE_PERMS); 
} 
 

11.2 Logging_Handler ÀÛ¼º

#include "ace/FILE_IO.h" 
#include "ace/SOCK_Stream.h" 
 
class ACE_Message_Block; // Forward declaration. 
 
class Logging_Handler 
{ 
protected: 
  // Reference to a log file. 
  ACE_FILE_IO &log_file_;  
 
  // Connected to the client. 
  ACE_SOCK_Stream logging_peer_;  
  // Receive one log record from a connected client.  <mblk>  
  // contains the hostname, <mblk->cont()> contains the log  
  // record header (the byte order and the length) and the data.  
  int recv_log_record (ACE_Message_Block *&mblk); 
 
  // Write one record to the log file. The <mblk> contains the  
  // hostname and the <mblk->cont> contains the log record.  
  int write_log_record (ACE_Message_Block *mblk); 
 
  // Log one record by calling <recv_log_record> and 
  // <write_log_record>.  
  int log_record ();  
} 
 
// µ¥ÀÌÅ͸¦ ¹Þ¾ÆµéÀ̰í, ¹Þ¾ÆµéÀÎ µ¥ÀÌÅÍ´Â CDRŬ·¡½º¸¦ ÀÌ¿ëÇØ¼­ ÇØ´õÆÄ½ÌÀ» ÇØ¼­ 
// ÇÊ¿äÇÑ Á¤º¸¸¦ ¾ò¾î¿Â´Ù. 
// ÃÖÁ¾ÀûÀ¸·Î´Â ACE_Message_Block chainÀ» ÀúÀåÇÑ´Ù. 
int Logging_Handler::recv_log_record (ACE_Message_Block *&mblk) 
{ 
  ACE_INET_Addr peer_addr; 
  logging_peer_.get_remote_addr (peer_addr); 
  mblk = new ACE_Message_Block (MAXHOSTNAMELEN + 1); 
  peer_addr.get_host_name (mblk->wr_ptr (), MAXHOSTNAMELEN); 
  mblk->wr_ptr (strlen (mblk->wr_ptr ()) + 1); // Go past name. 
 
  ACE_Message_Block *payload = 
    new ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE); 
  // Align Message Block for a CDR stream. 
  ACE_CDR::mb_align (payload); 
 
  if (logging_peer_.recv_n (payload->wr_ptr (), 8) == 8) { 
    payload->wr_ptr (8);     // Reflect addition of 8 bytes. 
 
    ACE_InputCDR cdr (payload); 
 
    ACE_CDR::Boolean byte_order; 
    // Use helper method to disambiguate booleans from chars. 
    cdr >> ACE_InputCDR::to_boolean (byte_order); 
    cdr.reset_byte_order (byte_order); 
 
    ACE_CDR::ULong length; 
    cdr >> length; 
 
    payload->size (8 + ACE_CDR::MAX_ALIGNMENT + length); 
 
    if (logging_peer_.recv_n (payload->wr_ptr(), length) > 0) { 
      payload->wr_ptr (length);   // Reflect additional bytes. 
      mblk->cont (payload); // Chain the header and payload. 
      return length; // Return length of the log record. 
    } 
  } 
  payload->release (); 
  mblk->release (); 
  payload = mblk = 0; 
  return -1; 
} 
 
// ·Î±× ÆÄÀÏ¿¡ ¸Þ½ÃÁö¸¦ ÀúÀåÇÑ´Ù. ¸¸¾à µð¹ö±ë flag°¡ ¼³Á¤µÇ¾î ÀÖ´Ù¸é  
// ¸Þ½ÃÁöÀÇ ³»¿ëÀ» Ç¥ÁØÃâ·ÂÇÑ´Ù. 
int Logging_Handler::write_log_record (ACE_Message_Block *mblk) 
{ 
  if (log_file_->send_n (mblk) == -1) return -1; 
 
  if (ACE::debug ()) { 
    ACE_InputCDR cdr (mblk->cont ());  
    ACE_CDR::Boolean byte_order; 
    ACE_CDR::ULong length; 
    cdr >> ACE_InputCDR::to_boolean (byte_order); 
    cdr.reset_byte_order (byte_order); 
    cdr >> length; 
    ACE_Log_Record log_record; 
    cdr >> log_record;  // Extract the <ACE_log_record>. 
    log_record.print (mblk->rd_ptr (), 1, cerr); 
  } 
 
  return mblk->total_length (); 
} 
 
int Logging_Handler::log_record () 
{ 
  ACE_Message_Block *mblk = 0; 
  if (recv_log_record (mblk) == -1) 
    return -1; 
  else { 
    int result = write_log_record (mblk); 
    mblk->release (); // Free up the entire contents. 
    return result == -1 ? -1 : 0; 
  } 
} 
 
 
 

 +-------------------+           +-------------------+ 
 | ACE_Message_Block |           | ACE_Message_Block | 
 +-------------------+           +-------------------+ 
 | cont() -----------|---------->| cont()            | 
 +-------------------+           +-------------------+ 
         |                                     | 
         |                                     | 
  +----------------+                      +----------------+    
  | ACE_Data_Block |                      | ACE_Data_Block | 
  +----------------+                      +----------------+ 
  | base() --------|----> HOSTNAME        | base() --------|--> LOGRECORD DATA 
  +----------------+                      +----------------+ 
     
 


11.3 Iterative Logging Server

°¡Àå ´Ü¼øÇÑ ÇüÅÂÀÇ ·Î±ë ¼­¹ö´Ù.

iterative server´Â Çѹø¿¡ ÇϳªÀÇ client¸¸ ¹Þ¾Æµé¿©¼­ ó¸®ÇÏ´Â °£´ÜÇÑ ÇüŸ¦ °¡Áø´Ù. ¸¸¾à 󸮵µÁß¿¡ »õ·Î¿î clientÀÇ ¿¬°á¿äûÀÌ µé¾î¿Â´Ù¸é, »õ·Î¿î client´Â ÀÌÀüÀÇ client¿¡ ´ëÇÑ ÀÛ¾÷À» ³¡³»±âÀü±îÁö ´ë±âÇØ¾ß ÇÑ´Ù.

ÀÌ·¯ÇÑ ¹æ½ÄÀÇ server´Â ÇнÀ¿ëÀ¸·Î´Â ¾µ¸¸ÇÒÁö ¸ð¸£Áö¸¸ °³¹ßÇÒ Çʿ䰡 ¾øÀ» °ÍÀÌ´Ù.
#include "ace/FILE_IO.h" 
#include "ace/INET_Addr.h" 
#include "ace/Log_Msg.h" 
#include "Logging_Server.h" 
#include "Logging_Handler.h" 
 
class Iterative_Logging_Server : public Logging_Server  
{ 
public: 
  Iterative_Logging_Server (): logging_handler_ (log_file_) {} 
 
  Logging_Handler &logging_handler () { 
    return logging_handler_;  
  } 
 
protected: 
  ACE_FILE_IO log_file_; 
  Logging_Handler logging_handler_; 
 virtual int open (u_short logger_port) {  
    if (make_log_file (log_file_) == -1) 
      ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "make_log_file()"), 
                        -1); 
    return Logging_Server::open (logger_port); 
  } 
 
  virtual int handle_connections () { 
    ACE_INET_Addr logging_peer_addr; 
 
    if (acceptor ().accept (logging_handler_.peer (), 
                            &logging_peer_addr) == -1) 
      ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "accept()"), -1); 
    ACE_DEBUG ((LM_DEBUG, "Accepted connection from %s\n", 
               logging_peer_addr.get_host_name ())); 
    return 0; 
  } 
 virtual int handle_data (ACE_SOCK_Stream *) { 
    while (logging_handler_.log_record () != -1) 
      continue; 
 
    logging_handler_.close (); // Close the socket handle. 
    return 0; 
  } 
} 
 

#include "ace/Log_Msg.h" 
#include "Iterative_Logging_Server.h" 
 
int main (int argc, char *argv[]) 
{ 
  Iterative_Logging_Server server; 
 
  if (server.run (argc, argv) == -1)  
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "server.run()"), 1); 
  return 0; 
} 
 

11.4 µ¿½Ã󸮸¦ À§Çؼ­ °í·ÁÇØ¾ß ÇÒ »çÇ×

µ¿½Ã󸮴 ³×Æ®¿öÅ© ÇÁ·Î±×·¥ÀÇ ¾ÈÁ¤¼º°ú ¼º´ÉÀû Ãø¸é¿¡¼­ ÇʼöÀûÀ¸·Î °í·ÁµÇ¾î¾ß ÇÏ´Â »çÇ×ÀÌ´Ù. ÀϹÝÀûÀ¸·Î ¼­¹ö ÇÁ·Î±×·¥ÀÇ °æ¿ì °í·ÁµÇ¾î¾ß ÇÏ´Â °ÍµéÀÌ ¸¹´Ù.

µ¿½Ãó¸®¿Í °ü·ÃµÇ¾î¼­ ¸¹Àº À̽´°¡ Á¦±âµÇ´Â ¿øÀÎÀº, ÇÁ·Î¼¼½º/¾²·¹µåÀÇ Á¦¾î(µ¿±âÈ­, Åë½Å, ¿î¿ë), Ŭ¶óÀÌ¾ðÆ® Á¤º¸ÀÇ À¯Áö¿Í ºÐ¼®µî¿¡ À־ ¼­¹öÀÇ ¸ñÀû°ú ±Ô¸ð¿¡ µû¶ó ´Ù¾çÇÑ ¹æ¹ýµéÀÌ ½ÃµµµÇ¾î¾ß Çϱ⠶§¹®ÀÌ´Ù.

¿©±â¿¡¼­´Â ´ÙÀ½°ú °°Àº ´Ù¾çÇÑ ¸ðµ¨ÀÇ µ¿½Ãó¸® ¹æ½Ä¿¡ ´ëÇØ¼­ »ìÆìº¸µµ·Ï ÇÒ °ÍÀÌ´Ù.
  1. ¼øÂ÷Àû ó¸® vs µ¿½Ãó¸®
  2. ´ÙÁß ÇÁ·Î¼¼½º ¹æ½Ä vs ´ÙÁß ¾²·¹µå ¹æ½Ä
  3. ÇÁ·Î¼¼½º/¾²·¹µå ó¸®
  4. User ¾²·¹µå vs Kernel(12) ¾²·¹µå vs hybrid ¾²·¹µå ¹æ½Ä
  5. ½ÃºÐÇÒ vs ½Ç½Ã°£ ½ºÄÉÁ층
  6. Task ±¸Á¶ vs ¸Þ½ÃÁö ±â¹Ý ±¸Á¶
11.4.1 Iterative(¼øÂ÷Àû ó¸®) ´ë µ¿½Ã ó¸®
iterative_concurrent.gif

  1. Iteratvie´Â ¸»±×´ë·Î Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÀ» ¼øÂ÷ÀûÀ¸·Î ó¸®ÇÏ´Â ¹æ½ÄÀÌ´Ù. ÇϳªÀÇ Å¬¶óÀ̾ðÆ®ÀÇ ¿äûÀÌ ³¡³ª¾ßÁö¸¸ ´ÙÀ½ Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÀÌ Ã³¸®µÉ ¼ö ÀÖ´Ù. 󸮿¡ °É¸®´Â ½Ã°£ÀÌ Âª°Å³ª, ¿äûÀÚü°¡ ÀûÀº °æ¿ì¿¡ °£´ÜÇÏ°Ô ±¸ÇöÇØ¼­ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
  2. µ¿½Ã 󸮴 µ¿½Ã¿¡ ¿©·¯°³ÀÇ Å¬¶óÀ̾ðÆ®ÀÇ ¿äûÀ» ¹Þ¾Æµé¿©¼­ À̸¦ ó¸®ÇÑ´Ù. ¿äûÀ» ó¸®Çϴµ¥ À־ ½Ã°£ÀÌ ¸¹ÀÌ °É¸®´Â I/O ÀÛ¾÷(DBȤÀº ÆÄÀÏ Á¢±Ù)ÀÌ ÇÊ¿äÇÒ °æ¿ì »ç¿ëµÉ ¼ö ÀÖ´Ù. ´ëºÎºÐÀÇ ¹Ù»Û ¼­¹ö¿¡¼­ äÅõǾîÁö°í ÀÖ´Â ¹æ¹ýÀÌ´Ù.

11.4.2 ´ÙÁß ÇÁ·Î¼¼½º ´ë ´ÙÁß ¾²·¹µå
  • ´ÙÁß ÇÁ·Î¼¼½º ¹æ½ÄÀº ¿äûÀÇ Ã³¸®¸¦ À§ÇÑ Å¬¶óÀÌ¾ðÆ®´ç º°°³ÀÇ ÇÁ·Î¼¼½º°¡ »ý¼ºµÇ´Â ¹æ½ÄÀÌ´Ù. »ý¼ºµÈ ÇÁ·Î¼¼½º´Â µ¶¸³ÀûÀ¸·Î ÀÛµ¿ÇÑ´Ù. - °¡»óÀÇ ¸Þ¸ð¸®¿Í ÀÔÃâ·ÂÁ¦¾î, ½Ã±×³Î Á¦¾î¸¦ ÇÑ´Ù. - ¶ÇÇÑ OS¿¡ ÀÇÇØ¼­ º¸È£µÈ´Ù. ÇÁ·Î¼¼½º°£ Åë½ÅÀ» À§Çؼ­ IPC(12)¸¦ ÀÌ¿ëÇÑ´Ù.

  • ´ÙÁß ¾²·¹µå´Â ÇϳªÀÇ ÇÁ·Î¼¼½º¿¡¼­ ¿©·¯°³ÀÇ ¾²·¹µå°¡ º´·ÄÀûÀ¸·Î ¹®¸ÆÀ» ±³È¯Çϸ鼭 ¿äûÀ» ó¸®ÇÏ´Â ¹æ½ÄÀÌ´Ù. °¢°¢ÀÇ ¾²·¹µå´Â ÇÁ·Î¼¼½º¿¡ Á¾¼ÓÀûÀ̸ç, ¸¹Àº ÀÚ¿øÀÌ ÇÁ·Î¼¼½º¿¡ ÀÇÇØ¼­ Àü¿ªÀûÀ¸·Î °ü¸®µÈ´Ù - Stack, registers, ½Ã±×³Î ¸¶½ºÅ©, TSD -. ¾²·¹µå´Â ´Ù¸¥ ¾²·¹µå·Î ºÎÅÍ º¸È£µÇÁö ¾Ê´Â´Ù. ¾²·¹µå°£ Åë½ÅÀ» À§Çؼ­ IPC¸¦ »ç¿ëÇÒ ¼öµµ ÀÖÁö¸¸, ¾²·¹µå°£ ½Ã±×³Î°ú Àü¿ªº¯¼ö¸¦ ÀÌ¿ëÇØ¼­ °ü¸®µÇ±âµµ ÇÑ´Ù.

11.5 ¾²·¹µåÇ® (Thread Pool)ÀÇ ¿î¿ë Àü·«

¸¹Àº ¾²·¹µå ÀÀ¿ë ÇÁ·Î±×·¥µéÀº ¾î¶°ÇÑ ÀÏÀÌ ¹ß»ýÇÒ °æ¿ì ÇØ´ç ÀÏÀ» ó¸®Çϱâ À§Çؼ­ »õ·Î¿î ¾²·¹µå¸¦ »ý¼ºÇÑ´Ù. Á÷°üÀûÀÎ ¹æ½ÄÀ̱ä ÇÏÁö¸¸ »õ·Î¿î ¾²·¹µå¸¦ »ý¼ºÇϱâ À§Çؼ­´Â ¸¹Àº ºñ¿ëÀÌ ¹ß»ý ÇÏ´Ù´Â ´ÜÁ¡À» °¡Áø´Ù. ÀÌ·¯ÇÑ ¹®Á¦ÀÇ ÇØ°áÀ» À§Çؼ­ ¾²·¹µå¸¦ ¹Ì¸® ¸¸µé¾î ³õ°í, ¿äûÀÌ µé¾î¿Ã°æ¿ì ƯÁ¤ ¾²·¹µå¿¡ ÀÛ¾÷À» ¸Ã±â±â À§Çؼ­ ¾²·¹µåÇ®À» ±¸¼ºÇÑ´Ù.

¾²·¹µåÇ®Àº ¾Æ·¡¿Í °°Àº ÀϹÝÀûÀÎ µÎ°¡Áö ¹æ¹ýÁß ÇϳªÀÇ ¹æ¹ýÀ» ¼±ÅÃÇÑ´Ù.
Upload new Attachment "prevents"

11.5.1 Half-Sync/Half-Async Pattern
µ¿±âÈ­¿Í ºñµ¿±âÈ­ ÆÐÅÏ ¸ðµÎ¸¦ Æ÷ÇÔÇÑ´Ù. ºñµ¿±â °èÃþÀº I/O À̺¥Æ®¿Í °°Àº ºñµ¿±âÀûÀÎ »ç°ÇÀ» ´Ù·é´Ù. µ¥ÀÌÅÍÀÇ Ã³¸®´Â µ¿±â°èÃþÀÇ ¾²·¹µåµéÀÌ ´ã´çÇÏ°Ô µÈ´Ù. µ¿±â°èÃþ°ú ºñµ¿±â°èÃþ°£ÀÇ µ¥ÀÌÅÍ Àü´ÞÀ» À§Çؼ­ ¿ÏÃæ¿µ¿ªÀÎ Queueing °èÃþÀÌ ÇÊ¿äÇÏ´Ù.

Upload new Attachment "halfsync_async.gif"

ÀÌ ÆÐÅÏÀº ´ÙÀ½°ú °°Àº ÀÕÁ¡À» °¡Áø´Ù.
  • Threads can be mapped to separate CPUs to scale up server performance via multi-processing
  • Each thread blocks independently, which prevents a flow-controlled connection from degrading the QoS that other clients receive

11.5.2 Half-Sync/Half-Async PatternÀÇ ´ÜÁ¡
Half-Sync/Half-Async ¾²·¹µå ¸ðµ¨Àº ÀϹÝÀûÀÎ ¾²·¹µå¹æ½Ä(¿äû´ç ¾²·¹µå »ý¼º)¿¡ ºñÇØ¼­ È¿À²ÀûÀ̸ç ÁÁÀº ¼º´ÉÀ» º¸¿©ÁÖ±ä ÇÏÁö¸¸ ´ÙÀ½°ú °°Àº ÇØ°áÇØ¾ßÇÒ ¹®Á¦Á¡µéÀ» °¡Áö°í ÀÖ´Ù. ÀÌ·¯ÇÑ ¹®Á¦µéÀº µ¿±â°èÃþ°ú ºñµ¿±â°èÃþÀ̶ó´Â ÀüÇô´Ù¸¥ ¼º°ÝÀÇ °èÃþÀ» ÇϳªÀÇ ½Ã½ºÅÛ¿¡ À¯ÁöÇÔÀ¸·Î ÁÖ·Î ¹ß»ýÇÑ´Ù.

  1. µ¿Àû ¸Þ¸ð¸® ÇÒ´ç¹× ÇØÁ¦
  2. °¢ ±â´ÉÀÇ µ¿±âÈ­
  3. ¹®¸Æ±³È¯
  4. CPU cache update
ÀÌ´Â ÀáÀçÀûÀÎ ¹®Á¦µé·Î ¼­¹ö¿¡ overhead¸¦ ÁÖ°í ¼º´ÉÀ» ¶³¾îÆ®¸± ¼ö ÀÖÀ¸¸ç, ´©ÀûµÉ °æ¿ì ¼­ºñ½º ÀÚü°¡ ºÒ°¡ÇÏ°Ô µÉ ¼öµµ ÀÖ´Ù.

À§ÀÇ ¹®Á¦´Â Leader/Followers architectural patternÀ» ÀÌ¿ëÇÔÀ¸·Î½á ÃÖ¼ÒÈ­ ½Ãų ¼ö ÀÖ´Ù.

11.5.3 Leader/Followers architectural pattern
ÀÌ ÆÐÅÏÀº Half-Sync/Half-Async ÀÇ Çâ»óµÈ ÆÐÅÏÀÌ´Ù. ´ÙÁß ¾²·¹µå´Â À̺¥Æ®¼Ò½º¸¦ °øÀ¯Çϸç, À̺¥Æ®¼Ò½º·Î ºÎÅÍÅÍ À̺¥Æ®°¡ ¹ß»ýÇÏ´Â Áö¸¦ ±â´Ù¸®°Ô µÈ´Ù. ÀÌ Half-sync/Half-AsyncÆÐÅÏ¿¡¼­ Reactor ¾²·¹µå°¡ ºÐ¸®µÇ°í, ºÐ¸®µÈ ¾²·¹µåÀÇ µ¿±âÈ­¸¦ À§ÇÑ ¿Àº£Çìµå¸¦ Á¦°ÅÇÑ´Ù.
       +------------------------+   demultiplexes 
       | Thread Poll            |<>---------------+ 
       +------------------------+                 | 
  +--<>| join()                 |                 | 
  |    | promote_new_leader()   |                 | 
  |    +------------------------+          +------------------+ 
  |          |                             | Event Handler    |     
  |          |  +--------+  uses           +------------------+ 
  |          +->| Handle | ----------------| handle_event()   | 
  |             +--------+ --------+       | get_handle()     |<|--+ 
  |                                |       +------------------+    | 
  |    +----------------------+    |                               | 
  +----| Handle Set           |<>--+                               | 
       +----------------------+            +------------------+    | 
       | handle_events()      |            | Concrete Event   |----+ 
       | deactivate_handle()  |            | Handler B        | 
       | reactivate_handle()  |            +------------------+ 
       | select()             |            | handle_event()   | 
       +----------------------+            | get_handle()     | 
                                           +------------------+ 
                                           +------------------+ 
                                           | Concrete Event   | 
                                           | Handler B        | 
                                           +------------------+ 
                                           | handle_event()   | 
                                           | get_handle()     | 
                                           +------------------+ 
 

11.6 Thread-perRequest On-demand Spawning Strategy

¿äûÀ» ¹Þ´Â ¾²·¹µå¸¦ µû·Î ºÐ¸®Çؼ­, Ŭ¶óÀÌ¾ðÆ® ¿¬°áÀ̳ª, µ¥ÀÌÅÍ ¿äûÀÌ µé¾î¿ÔÀ» ¶§, ¿äûÀ» ó¸®ÇÒ »õ·Î¿î ÇÁ·Î¼¼½º³ª ¾µ·¹µå¸¦ »ý¼ºÇÏ´Â ¹æ½ÄÀÌ´Ù. º¸Åë thread-per-request¿Í thread-per-connectionÇü½ÄÀ¸·Î ³Î¸® »ç¿ëµÇ°í ÀÖ´Ù.

ÇÊ¿äÇÒ ¶§¸¸ ¾²·¹µå¸¦ »ý¼º½ÃŰ¸é µÇ¹Ç·Î ÀÚ¿øÀÇ ¼Òºñ¸¦ ÁÙÀÏ ¼ö ÀÖ´Ù´Â ÀåÁ¡À» °¡ÁöÁö¸¸, ¾²·¹µå¿Í ÇÁ·Î¼¼½º¸¦ ¸Å¹ø »õ·Î »ý¼º½ÃÄÑ¾ß Çϱ⠶§¹®¿¡, ½Ç½Ã°£¼ºÀ» Áß¿äÇϽà Çϰųª, ¸¹Àº ¼öÀÇ ¿¬°á/¿äûÀÌ ÀÖ´Â ¼­ºñ½º¿¡´Â »ç¿ëÇϱâ Èûµé´Ù´Â ´ÜÁ¡À» °¡Áø´Ù.

12 N:1 ¿Í 1:1 ¾²·¹µå ¸ðµ¨

ÃÖ±Ù¿¡´Â ÄÄÇ»ÆÃÆÄ¿ö¸¦ ³ôÀ̱â À§Çؼ­ 2°³ ÀÌ»óÀÇ CPU°¡ ÀåÂøµÇ´Â °æ¿ì¸¦ ÈçÈ÷ º¼ ¼ö ÀÖ´Ù. ÀÌ·²°æ¿ì ¿î¿µÃ¼Á¦´Â ´Ù¼öÀÇ CPU¸¦ È¿À²ÀûÀ¸·Î °ü¸®Çϱâ À§Çؼ­ ÇÁ·Î¼¼½º¸¦ °¢ CPU¿¡ ÇÒ´ç½ÃÄѼ­ °¡´ÉÇÑ ÇÊ¿äÇÑ ÀÏÀ» ºü¸£°Ô ó¸®ÇÒ ¼ö ÀÖµµ·Ï ½ºÄÉÁ층À» ÇØÁÖ¾î¾ß ÇÑ´Ù. ¾²·¹µå¿ª½Ã ¸¶Âù°¡Áö·Î ´Ù¼öÀÇ CPU°¡ ÀÖ´Ù¸é, ¾²·¹µå¸¦ È¿°úÀûÀ¸·Î ½ºÄÉÁ층ÇÒ ¼ö ÀÖµµ·Ï OS¿¡¼­ Áö¿øÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ÃÖ±ÙÀÇ OS´Â ¾²·¹µå¸¦ ½ºÄÉÁ층Çϱâ À§ÇÑ ´Ù¾çÇÑ ¹æ½ÄÀ» Á¦°øÇϰí ÀÖ´Ù.

ÀÌ·¯ÇÑ ¾²ÄÉÁ층 ¹æ½ÄÀº Å©°Ô N:1 ¹æ½Ä¿Í 1:1¹æ½Ä µÎ°¡Áö°¡ Á¸ÀçÇÑ´Ù.

Upload new Attachment "thread_model.gif"

  1. Process contention scope : ÇϳªÀÇ ¾²·¹µå´Â µ¿ÀÏÇÑ CPU¿¡¼­ ó¸®ÇÏ´Â ¹æ½ÄÀ¸·Î user threading ¸ðµ¨À̶ó°í ºÒ¸®¿ì±âµµ ÇÑ´Ù.
  2. System contention scope : CPU°¡ ¸î°³µç °ü°è¾øÀÌ, System ¿µ¿ª¿¡¼­ ¾²·¹µå°¡ 󸮵ȴÙ. ´ÜÀÏÀÇ CPUó·³ º¸°í ó¸®ÇÏ´Â ¹æ½ÄÀ̶ó°í º¸¸é µÈ´Ù. kernel threading ¸ðµ¨À̶ó°í ºÒ¸®¿ì±âµµ ÇÑ´Ù.

¸î¸î ¿î¿µÃ¼Á¦(Solaris¿Í °°Àº)´Â N:1°ú 1:1 ¹æ½ÄÀ» ÇÔ²² Áö¿øÇÏ´Â N:M ¹æ½ÄÀÇ hybrid-threading modelÀ» Áö¿øÇϱ⵵ ÇÑ´Ù. ¿î¿µÃ¼Á¦ÀÇ ¾²·¹µå ¶óÀ̺귯¸®´Â ±âº»ÀûÀ¸·Î user-space ¾²·¹µå¸¦ »ý¼º½Ã۰í, ¿ä±¸µÉ ¶§¿¡¸¸ system contention ¾²·¹µå¸¦ »ý¼º½ÃŲ´Ù.

13 Task- vs. Message-based Concurrency Architectures

concurrency architecture(±¸Á¶)´Â ´ÙÀ½°ú °°Àº ¿ä¼Òµé·Î ±¸¼ºµÈ´Ù.
  1. CPUs : ¾ÖÇø®ÄÉÀ̼ÇÀÇ ½ÇÇàÄÚµå
  2. Data & control message : ³×Æ®¿öÅ© ÀåÄ¡·Î ºÎÅÍ ÁÖ°í ¹Þ´Â µ¥ÀÌÅ͵é
  3. Service processing task : ¸Þ½ÃÁö³ª µ¥ÀÌÅ͸¦ ¹Þ¾Æ¼­ ¼öÇàÇÏ´Â ¼­ºñ½º

  4. Task base concurrency ±¸Á¶´Â ¼­ºñ½º ´ÜÀ§·Î ´Ù¼öÀÇ CPUs¸¦ ¼öÇàÇÏ´Â ¹æ½ÄÀÌ´Ù.
  5. Message base concurrency ±¸Á¶´Â ¾îÇø®ÄÉÀÌ¼Ç È¤Àº ³×Æ®¿öÅ© ÀåÄ¡¸¦ ÅëÇØ¼­ Àü´ÞµÇ´Â ¸Þ½ÃÁö ´ÜÀ§·Î CPUs¸¦ ÇÒ´çÇÏ´Â ¹æ½ÄÀÌ´Ù.

14 Overview of OS Concurrency(Çù·Â) Mechanisms

¸¹Àº °æ¿ì ³×Æ®¿öÅ© ¾ÖÇø®ÄÉÀ̼ǵéÀº ¼­ºñ½º ¿äûÀ» ÇØ°áÇϱâ À§Çؼ­ ´Ù¼öÀÇ ÇÁ·Î¼¼½º¸¦ »ý¼º½ÃÄÑ¾ß Çϸç, À̵é ÇÁ·Î¼¼½º°£¿¡ Çù·ÂÀ» À¯ÁöÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. À̹ø Àå¿¡¼­´Â ÀÌ·¯ÇÑ Çù·ÂÀÇ À¯Áö¸¦ À§ÇÑ ¾Æ·¡ÀÇ ÁÖÁ¦µé¿¡ ´ëÇØ¼­ ´Ù·ê °ÍÀÌ´Ù.
  1. Synchronous event demultiplexing
  2. Multiprocessing
  3. Multi threading 1. Synchronization
¶ÇÇÑ C¿¡¼­ Á¦°øÇÏ´Â concurrency API¸¦ ÀÌ¿ëÇØ¼­ ³×Æ®¿öÅ© ¾ÖÇø®ÄÉÀ̼ÇÀ» ¸¸µå´Â ¹æ¹ý°ú ¹ß»ýÇÒ ¼ö ÀÖ´Â ¿©·¯°¡Áö ¹®Á¦Á¡/ÇØ°á¹æ¾È µî¿¡ ´ëÇØ¼­ Åä·ÐÇϵµ·Ï ÇϰڴÙ.

14.1 Synchronous Event Demultiplexing

´Ù¼öÀÇ ¸Þ½ÃÁö¸¦ ó¸®ÇÏ´Â °¡Àå ¼Õ½¬¿î ¹æ½ÄÀº ¸Þ½ÃÁö°¡ µé¾î¿À¸é À̸¦ ¹öÆÛ¿¡ ´ã¾ÆµÎ°í, À̺¥Æ®¸¦ ¹ß»ý½ÃŲ´ÙÀ½ ÀÏÁ¤½Ã°£ °£°Ý(Áï µ¿±âÀû)À¸·Î À̺¥Æ®°¡ µµÂøÇß´ÂÁö¸¦ È®ÀÎÇØ¼­, À̺¥Æ®°¡ ÀÖ´Ù¸é ¹öÆÛ¿¡ ÀÖ´Â ¸Þ½ÃÁö¸¦ Àоîµé¿©¼­ ó¸®ÇÏ´Â ¹æ½ÄÀÏ °ÍÀÌ´Ù.

ÀÌ·¯ÇÑ À̺¥Æ® µ¿±âÈ­¸¦ ÀÌ¿ëÇÑ ¸Þ½ÃÁö󸮸¦ À§Çؼ­ Unix ½Ã½ºÅÛÀº poll()°ú select(), windows´Â WaitForMultipleObjects()¿Í °°Àº ÇÔ¼ö¸¦ Á¦°øÇÑ´Ù. ÀÌÁß select()°¡ À̺¥Æ® ±â¹ÝÀÇ ´ÙÁß ÀÔÃâ·Â µ¥ÀÌÅ͸¦ ó¸®Çϱâ À§ÇÑ °¡Àå ÀϹÝÀûÀÎ ÇÔ¼ö·Î »ç¿ëµÈ´Ù.

select()¿¡ ´ëÇÑ ³»¿ëÀº select man page¸¦ Âü°íÇϱ⠹ٶõ´Ù.

14.2 ¸ÖƼ Processing ¹æ½Ä

¸ÖƼ Processing´Â ´Ù¼öÀÇ ÇÁ·Î¼¼½º¸¦ »ý¼º½ÃÄѼ­ ¿äûÀ» ó¸®ÇÏ´Â ¹æ½ÄÀÌ´Ù. UnixÀÇ °æ¿ì fork()¿Í exec()ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ÇÁ·Î¼¼½º¸¦ »ý¼º½Ãų ¼ö ÀÖÀ¸¸ç, windowsÀÇ °æ¿ì CreateProcess()ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ »õ·Î¿î ÇÁ·Î¼¼½º¸¦ »ý¼º½Ãų ¼ö ÀÖ´Ù.

¸ÖƼ ÇÁ·Î¼¼½Ì¹æ½ÄÀ» ÀÌ¿ëÇÒ °æ¿ì, ÇÁ·Î¼¼½º µ¿±âÈ­°¡ Áß¿äÇÑ À̽´°¡ µÇ´Âµ¥ À¯´Ð½ºÀÇ °æ¿ì wait(), waitpid() À©µµ¿ìÁîÀÇ °æ¿ì WaitForSignalObject(), WaitForMultipleObjects()¿Í °°Àº ÇÁ·Î¼¼½º µ¿±âÇÔ¼ö¸¦ Áö¿øÇÑ´Ù.

14.3 ¸ÖƼ ¾²·¹µå ¹æ½Ä

¿î¿µÃ¼Á¦´Â ¸ÖƼ ¾²·¹µå¸¦ Áö¿øÇϱâ À§Çؼ­ ¾²·¹µå »ý¼º/Á¾·á, ¾²·¹µå µ¿±âÈ­, ¾²·¹µå Ư¼º, ¾²·¹µå ¸Þ¸ð¸®°ü¸®¸¦ À§ÇÑ ÇÔ¼öµéÀ» Á¦°øÇÑ´Ù.

À̵é ÇÔ¼ö¿¡ ´ëÇÑ ³»¿ëÀº Pthread API¸¦ Âü°íÇϱ⠹ٶõ´Ù.

14.4 ¾²·¹µå µ¿±âÈ­

¾²·¹µå´Â ÆÄÀÏ, ³×Æ®¿öÅ© ÀåÄ¡, µ¥ÀÌŸº£À̽º, °øÀ¯¸Þ¸ð¸®µîÀÇ ÀÚ¿øÀ» °øÀ¯Çؼ­ Á¢±ÙÇÏ´Â °æ¿ì°¡ ÀÚÁÖ ¹ß»ýÇÑ´Ù. ±×·¯¹Ç·Î ÀÌµé °øÀ¯µÈ ÀÚ¿ø¿¡ ´ëÇÑ µ¿±âÈ­°¡ ÇÊ¿äÇÏ°Ô µÈ´Ù. ´ÙÀ½Àº µ¿±âÈ­¸¦ À§Çؼ­ »ç¿ëÇÒ ¼ö ÀÖ´Â µµ±¸µéÀÌ´Ù.
  1. Mutex
  2. »ç¿ë semaphore
  3. Á¶°Çº¯¼ö
  4. Read/Write lock

15 ACE Event Demuxing Wrapper Facades

EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù.