ÃÑ ÆäÀÌÁö ¼ö : 3224
![]()
|
Facebook Joinc ±×·ì
Joinc QA »çÀÌÆ®
![]()
Tweet
joinc´Â Firefox¿Í chrome¿¡¼ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù.
1 ³×Æ®¿öÅ© ÇÁ·Î±×·¥À» ÀÛ¼ºÇÏ´Â°Ç ¾î·Á¿î ÀÏÀÌ´Ù.
°ß°íÇϰí È¿À²ÀûÀ̸ç, È®Àå ¿ëÀÌÇÏ°í °Ô´Ù°¡ ´ÙÁßÀÇ Å¬¶óÀ̾ðÆ®ÀÇ ¿ä±¸¸¦ ó¸®ÇØ¾ß ÇÏ´Â ³×Æ®¿öÅ© ¾ÖÇø®ÄÉÀ̼ÇÀ» ÀÛ¼ºÇÏ´Â °ÍÀº ¸Å¿ì Èûµç ÀÏÀÌ´Ù. ¸ðµç ÀÌ·± ÇÁ·Î±×·¥À» ¸¸µé±â À§Çؼ´Â ³×Æ®¿öÅ©¿¡ ´ëÇÑ Áö½Ä»Ó¸¸ ¾Æ´Ï¶ó ½Ã½ºÅÛ ÇÁ·Î±×·¡¹Ö¿¡ ´ëÇÑ ±íÀº Áö½ÄÀ» ÇÊ¿ä·Î ÇÑ´Ù. Ȥ½Ã³ª ´Ù¾çÇÑ Ç÷§ÆûÀ» Áö¿øÇØ¾ß Çϴ°æ¿ì´Â ´õ¿í ±×·¯ÇÏ´Ù.
ÀÌ·¸°Ô ÇÁ·Î±×·¥ÀÇ ÀÛ¼ºÀÌ º¹ÀâÇØÁö´Â °ÍÀº ´ÙÀ½°ú °°Àº ÀÌÀ¯µé ¶§¹®ÀÌ´Ù.
2 °´Ã¼ÁöÇâÀ» ÅëÇÑ ¼ÒÇÁÆ®¿þ¾î ǰÁú Çâ»ó
3 Á¤º¸Ã³¸® ±â¼úÀÇ ÁøÈ
Á¤º¸Ã³¸®¸¦ À§ÇÑ ±âº» ÀÚ¿øÀÎ CPU¿Í ³×Æ®¿öÅ©´Â ¸Å³â 3-7¹è Á¤µµ°¡ ´õ »¡¶óÁö°í ÀÖÀ¸¸ç, 2010³â °æ¿¡´Â ´ë·« ¾Æ·¡¿Í °°Àº ¼öÁرîÁö ¹ßÀüÇÒ °ÍÀ¸·Î ¿¹»óµÇ°í ÀÖ´Ù.
4 ACEÀÇ Æ¯Â¡![]()
ACE´Â ´ÙÀ½°ú °°ÀÌ °³¹ßµÇ¾îÁö°í ÀÖ´Ù.
4.1 ACE°¡ Áö¿øÇÏ´Â Ç÷¿Æû
5 ACE ÇÁ·¹ÀÓ¿öÅ©+------------+ +------------+ +------------+ | Acceptor |------->| Reactor |<--------| Proactor | | Connector | | | | | +------------+ +------------+ +------------+ +--------------+ +------------+ +------------+ | Service |----->| Streams |-------->| Task | | Configurator | | | | | +--------------+ +------------+ +------------+
6 ¿¬°áÁöÇâ ÇÁ·ÎÅäÄݰú ºñ¿¬°áÁöÇâ ÇÁ·ÎÅäÄÝÀÇ ºñ±³
¸¹Àº ÇÁ·ÎÅäÄݵéÀº º»°ÝÀûÀ¸·Î µ¥ÀÌÅ͸¦ ÀÔÃâ·ÂÇϱâ Àü¿¡ ¿¬°áÀ» ¸Î´Â ÀÛ¾÷À» ÇÑ´Ù. °¡Àå ´ëÇ¥ÀûÀÎ °æ¿ì´Â Àüȸ¦ ÇÏ´Â °æ¿ì´Ù. Àüȸ¦ ÇØ¼ º»°ÝÀûÀ¸·Î ´ëȸ¦ ³ª´©±â Àü¿¡ º¸Åë ´ëÈÀÇ »ó´ë°¡ ¿Ã¹Ù¸¥Áö È®ÀÎÇϱâ À§ÇÑ ÀÛ¾÷ÀÌ ÀÌ·ç¾îÁø´Ù. Connector Accoptor
| |
| 1. SYN |
| --------------------> |
| <-------------------- |
| 2. SYN/ACK |
| 3. ACK |
| --------------------> |
| 4. |
| <-------------------> |
| |
TCP/IP 3-Way handshake
1. Àú´Â ´©±¸ÀÔ´Ï´Ù. ¾Æ¹«°³¾¾ ¸Â½À´Ï±î ?
2. ³» ´©±¸´©±¸ ¸Â½À´Ï´Ù.
3. ÇÏ°í ½ÍÀº ¾ê±â°¡ ÀÖ¾î¼ ÀüÈ µå·È½À´Ï´Ù.
4. ÀÌ·± Àú·± ´ëÈ
³×Æ®¿öÅ© »óÀÇ µ¥ÀÌÅͱ³È¯ ¿ª½Ã À§¿¡¼ ó·³ ¿¬°áÀ» ¸Î´Â °úÁ¤À» °ÅÄ¡´Â ÇÁ·ÎÅäÄÝÀÌ ÀÖÁö¸¸ ±×·¸Áö ¾ÊÀº °æ¿ìµµ ÀÖ´Ù. ¾î¶² ÇÁ·ÎÅäÄÝÀ» »ç¿ëÇÒÁö´Â ¸¸µé°íÀÚ ÇÏ´Â ³×Æ®¿öÅ© ¼ºñ½º¿¡ µû¶ó¼ ´Þ¶óÁú ¼ö ÀÖ´Ù.6.1 ¿¬°áÁöÇâ ÇÁ·ÎÅäÄÝ
6.2 ºñ¿¬°áÁöÇâ ÇÁ·ÎÅäÄÝ
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 ¼ÒÄϰú È¥µ¿ÇÏÁö ¸»±â ¹Ù¶õ´Ù.
8.1 ¸Þ½ÃÁö Àü´Þ°ú °øÀ¯ ¸Þ¸ð¸® +-------------+ +-------------+
| CLIENT | | SERVER |
| | | |
| | | |
+-------------+ +-------------+
| |
| MSG ---> |
+-----------------------------------+
IPC(12)
¸Þ½ÃÁö Àü´Þ(Message Passing)´Â IPC ¼³ºñ¸¦ ÀÌ¿ëÇØ¼ µ¥ÀÌÅ͸¦ Àü´ÞÇÑ´Ù. °³¹ßÀÚµéÀº ó¸®ÇؾßÇÒ µ¥ÀÌÅ͸¦ ¸íÈ®È÷ Çϱâ À§Çؼ ÇÁ·ÎÅäÄÝÀ» Á¤ÀÇÇØ¼ »ç¿ëÇÏ°Ô µÈ´Ù.
+-------------+ +-------------+
| CLIENT | | SERVER |
| | | |
| +--------------------------------+ |
| | | | | |
+------|------+ +------|------+
| °øÀ¯ ¸Þ¸ð¸® ¿µ¿ª |
| |
+--------------------------------+
°øÀ¯¸Þ¸ð¸®´Â ´Ù¼öÀÇ ÇÁ·Î¼¼½º°¡ ÇϳªÀÇ ¸Þ¸ð¸® ¿µ¿ªÀ» ÅëÇØ¼ µ¥ÀÌÅ͸¦ ±³È¯ÇÒ ¼ö ÀÖµµ·Ï Çã¿ëÇÑ´Ù. ´Ù¼öÀÇ ÇÁ·Î¼¼½º°¡ ¸Þ½ÃÁö Àü´Þ ¹æ½ÄÀ» ÀÌ¿ëÇÒ °æ¿ì µ¿ÀÏÇÑ µ¥ÀÌÅͰ¡ ¿©·¯¹ø º¹»çµÈ´Ù´Â ´ÜÁ¡ÀÌ Àִµ¥, °øÀ¯¸Þ¸ð¸®¸¦ ÀÌ¿ëÇÒ °æ¿ì ÇϳªÀÇ ¸Þ½ÃÁö¸¸ »ç¿ëÇÏ¸é µÇ¹Ç·Î È¿À²ÀÌ ³ô¾ÆÁö°Ô µÈ´Ù. ±×·¯³ª Á¦¾îÇϱ⠱î´Ù·Ó´Ù´Â ´ÜÁ¡À» °¡Áø´Ù.9 Socket »ìÆìº¸±â
Socket´Â ¿î¿µÃ¼Á¦¿¡ »ó°ü¾øÀÌ ³×Æ®¿öÅ© Åë½Å ÇÁ·Î±×·¡¹ÖÀÌ °¡´ÉÇϵµ·Ï ÀϹÝÀûÀÎ API¸¦ Á¦°øÇÑ´Ù. Socket´Â ´ÙÀ½°ú °°Àº Ư¡À» °¡Áø´Ù.
9.1 Socket Dimensions![]()
9.2 Socket API
socket layer ¼Ò°³¹®¼¸¦ Âü°íÇϱ⠹ٶõ´Ù. 9.3 Socket ÀÇ ÇѰè
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ÀÇ ¹®Á¦µéÀ» ÇØ°áÇϰí ÀÖ´Ù.
![]() 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¿µ¿ªÀ¸·Î ³ª´©¾î¼ º¸¿©ÁÖ°í ÀÖ´Ù. ![]()
ACE Socket wrapper facade class´Â ´ÙÀ½°ú °°Àº ±â´ÉµéÀ» Á¦°øÇÑ´Ù.
9.8 ACE Socket Wrapper FacadesÀÇ ±ÔÄ¢
Socket API¿¡¼ ´Éµ¿ÀûÀ¸·Î ¿¬°áÇϱâ À§ÇÑ connect()ÇÔ¼ö¿Í ´Éµ¿ÀûÀ¸·Î ¿¬°áÇϱâ À§Çؼ accept()ÇÔ¼ö¸¦, ¸¶Áö¸·À¸·Î Åë½ÅÀ» À§Çؼ read(), write()ÇÔ¼ö¸¦ »ç¿ëÇÏ´Â °Í°ú ¸¶Âù°¡Áö·Î, active connection role °ú passive connection role, communication roleÀ» °¡Áö°í ÀÖ´Ù.
+----------------------------+ +----------------------------+ | 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 |
|--------------------------------------------------|
| + 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 |
+-----------------------------+
| - 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 | | 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 ÀÇ Æ¯Â¡
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¿¡ µû¶ó¼ ´ÙÀ½°ú °°Àº ÇൿÀ» ÇÑ´Ù.
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 Ŭ·¡½º´Â ´ÙÀ½°ú °°Àº ±â´ÉÀ» Á¦°øÇÑ´Ù.
+---------------+ +------------------------------------------------+
| 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;
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 Ŭ·¡½º´Â À§ÀÇ ¹®Á¦¸¦ ÇØ°áÇÒ ¼ö ÀÖ´Â ´ÙÀ½°ú °°Àº ±â´ÉµéÀ» Á¦°øÇÑ´Ù.
+---------------+ +---------------+ +-----------------+
| 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() | |++++| +----+ +-------------------+ +-------------------+ +----+ | | +----+ +----+ |++++| |++++| +----+ +----+³×Æ®¿öÅ© ¾ÖÇø®ÄÉÀ̼ǿ¡¼ÀÇ ÇÙ½ÉÀº °á±¹ ¿äû°ú ÀÀ´äÀ̰í, ¿äû°ú ÀÀ´äÀº ¸Þ½ÃÁö¸¦ ÁÖ°í ¹ÞÀ½À¸·Î½á ÀÌ·ç¾îÁø´Ù´Â Á¡¿¡¼ ¸Þ½ÃÁö¸¦ ¾î¶»°Ô È¿°úÀûÀ¸·Î Àß Ã³¸®ÇÏ´À³Ä°¡ °¡Àå Áß¿äÇÑ ÇÙ½ÉÀ̶ó°í ÇÒ ¼ö ÀÖ´Ù. ¸Þ½ÃÁö¸¦ Á¦´ë·Î ó¸®Çϱâ À§Çؼ´Â ´ÙÀ½°ú °°Àº »çÇ×µéÀÌ ÃæÁ·µÇ¾î¾ß ÇÑ´Ù.
+-----------------------------------------------+ | 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´Â ÇϳªÀÇ ´ÜÀÏÇÑ Çü½ÄÀ» °¡Áö´Â µ¥ÀÌÅ͸¦ Æ÷ÀÎÆ®ÇÑ´Ù.
¹Ý¸é µÎ°³ÀÌ»óÀÇ 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 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 µ¿½Ã󸮸¦ À§Çؼ °í·ÁÇØ¾ß ÇÒ »çÇ×
µ¿½Ã󸮴 ³×Æ®¿öÅ© ÇÁ·Î±×·¥ÀÇ ¾ÈÁ¤¼º°ú ¼º´ÉÀû Ãø¸é¿¡¼ ÇʼöÀûÀ¸·Î °í·ÁµÇ¾î¾ß ÇÏ´Â »çÇ×ÀÌ´Ù. ÀϹÝÀûÀ¸·Î ¼¹ö ÇÁ·Î±×·¥ÀÇ °æ¿ì °í·ÁµÇ¾î¾ß ÇÏ´Â °ÍµéÀÌ ¸¹´Ù.
µ¿½Ãó¸®¿Í °ü·ÃµÇ¾î¼ ¸¹Àº À̽´°¡ Á¦±âµÇ´Â ¿øÀÎÀº, ÇÁ·Î¼¼½º/¾²·¹µåÀÇ Á¦¾î(µ¿±âÈ, Åë½Å, ¿î¿ë), Ŭ¶óÀÌ¾ðÆ® Á¤º¸ÀÇ À¯Áö¿Í ºÐ¼®µî¿¡ ÀÖ¾î¼ ¼¹öÀÇ ¸ñÀû°ú ±Ô¸ð¿¡ µû¶ó ´Ù¾çÇÑ ¹æ¹ýµéÀÌ ½ÃµµµÇ¾î¾ß Çϱ⠶§¹®ÀÌ´Ù.
¿©±â¿¡¼´Â ´ÙÀ½°ú °°Àº ´Ù¾çÇÑ ¸ðµ¨ÀÇ µ¿½Ãó¸® ¹æ½Ä¿¡ ´ëÇØ¼ »ìÆìº¸µµ·Ï ÇÒ °ÍÀÌ´Ù.
11.4.1 Iterative(¼øÂ÷Àû ó¸®) ´ë µ¿½Ã ó¸®![]()
11.4.2 ´ÙÁß ÇÁ·Î¼¼½º ´ë ´ÙÁß ¾²·¹µå
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"
ÀÌ ÆÐÅÏÀº ´ÙÀ½°ú °°Àº ÀÕÁ¡À» °¡Áø´Ù.
11.5.2 Half-Sync/Half-Async PatternÀÇ ´ÜÁ¡
Half-Sync/Half-Async ¾²·¹µå ¸ðµ¨Àº ÀϹÝÀûÀÎ ¾²·¹µå¹æ½Ä(¿äû´ç ¾²·¹µå »ý¼º)¿¡ ºñÇØ¼ È¿À²ÀûÀ̸ç ÁÁÀº ¼º´ÉÀ» º¸¿©ÁÖ±ä ÇÏÁö¸¸ ´ÙÀ½°ú °°Àº ÇØ°áÇØ¾ßÇÒ ¹®Á¦Á¡µéÀ» °¡Áö°í ÀÖ´Ù. ÀÌ·¯ÇÑ ¹®Á¦µéÀº µ¿±â°èÃþ°ú ºñµ¿±â°èÃþÀ̶ó´Â ÀüÇô´Ù¸¥ ¼º°ÝÀÇ °èÃþÀ» ÇϳªÀÇ ½Ã½ºÅÛ¿¡ À¯ÁöÇÔÀ¸·Î ÁÖ·Î ¹ß»ýÇÑ´Ù.
À§ÀÇ ¹®Á¦´Â 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"
13 Task- vs. Message-based Concurrency Architectures
concurrency architecture(±¸Á¶)´Â ´ÙÀ½°ú °°Àº ¿ä¼Òµé·Î ±¸¼ºµÈ´Ù.
14 Overview of OS Concurrency(Çù·Â) Mechanisms
¸¹Àº °æ¿ì ³×Æ®¿öÅ© ¾ÖÇø®ÄÉÀ̼ǵéÀº ¼ºñ½º ¿äûÀ» ÇØ°áÇϱâ À§Çؼ ´Ù¼öÀÇ ÇÁ·Î¼¼½º¸¦ »ý¼º½ÃÄÑ¾ß Çϸç, À̵é ÇÁ·Î¼¼½º°£¿¡ Çù·ÂÀ» À¯ÁöÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. À̹ø Àå¿¡¼´Â ÀÌ·¯ÇÑ Çù·ÂÀÇ À¯Áö¸¦ À§ÇÑ ¾Æ·¡ÀÇ ÁÖÁ¦µé¿¡ ´ëÇØ¼ ´Ù·ê °ÍÀÌ´Ù.
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 ¾²·¹µå µ¿±âÈ
¾²·¹µå´Â ÆÄÀÏ, ³×Æ®¿öÅ© ÀåÄ¡, µ¥ÀÌŸº£À̽º, °øÀ¯¸Þ¸ð¸®µîÀÇ ÀÚ¿øÀ» °øÀ¯Çؼ Á¢±ÙÇÏ´Â °æ¿ì°¡ ÀÚÁÖ ¹ß»ýÇÑ´Ù. ±×·¯¹Ç·Î ÀÌµé °øÀ¯µÈ ÀÚ¿ø¿¡ ´ëÇÑ µ¿±âȰ¡ ÇÊ¿äÇÏ°Ô µÈ´Ù. ´ÙÀ½Àº µ¿±âȸ¦ À§Çؼ »ç¿ëÇÒ ¼ö ÀÖ´Â µµ±¸µéÀÌ´Ù.
15 ACE Event Demuxing Wrapper Facades |
|
|||||||||||||||||||||||||||||||||||
|
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù. |
|