ë§Œë¬¼ì˜ ê·¼ì›ì€ 불 - í—¤ë¼í´ë ˆì´í† 스(Herakleiros)
1 시작하며 #
ì´ íŠœí† ë¦¬ì–¼ì—서는, 우리는 ì²˜ìŒ íŠœí† ë¦¬ì–¼ì—서 ë°°ì› ë˜ ìž‘ì€ ì„œë²„ 하나와 몇가지 추가ì ì¸ ê²ƒë“¤ì„ ë¹Œë“œí• ê²ƒì´ë‹¤. ì´ ê¸€ 마지막ì—는 ë” ê´œì°®ì€ ì„œë²„ ê°ì²´ë¥¼ 만들 것ì´ë‹¤. ì´ê²ƒì€ ë” ë‹¨ìˆœí•˜ê³ ì´ì „ì— ë§Œë“¤ì—ˆë˜ ê²ƒë³´ë‹¤ ë” ê´€ë¦¬í•˜ê¸°ê°€ 쉬운 것ì´ë‹¤.
ì‹œìž‘í•˜ê¸°ì „ì— ìš°ë¦¬ ìžì‹ ì—게 íŠœí† ë¦¬ì–¼ 1ì—서 í–ˆë˜ ì§ˆë¬¸ì„ ë‹¤ì‹œ í•´ë³´ìž :
서버를 ìƒì„±í•˜ëŠ” ë° í•„ìš”í•œ ê²ƒì€ ë¬´ì—‡ì¸ê°€?
- í´ë¼ì´ì–¸íŠ¸ë“¤ë¡œë¶€í„° ì ‘ì†ì„ 받아들ì´ëŠ”(accept) ì–´ë–¤ 것
- ì„¤ì¹˜ëœ ì ‘ì†ë“¤ì„ ì œì–´í•˜ëŠ” ì–´ë–¤ 것
- ì´ê²ƒë“¤ 모ë‘를 ì œì–´í•˜ëŠ” ë©”ì¸ í”„ë¡œê·¸ëž¨ 루프
2 다시 ë©”ì¸ í•¨ìˆ˜ #
íŠœí† ë¦¬ì–¼ 1ê³¼ ê°™ì´, ì´ê²ƒ ë˜í•œ ì •ë§ë¡œ ìž‘ì€ í”„ë¡œê·¸ëž¨ì´ë‹¤. 나는 새로운 ì•„ì´ë””어를 ë„ìž…í•´ ë¶™ì¼ ê²ƒì´ì§€ë§Œ ì´ê²ƒì€ ë˜í•œ acceptor를 단순화시키기 위해 치장하는 것ì´ë¼ ìƒê°í•˜ë©´ ëœë‹¤.
Kirthikaì˜ ê°œìš”ëŠ” 다ìŒê³¼ 같다 :
ì´ê²ƒì€ ACEì˜ ì‰½ê²Œ êµ¬í• ìˆ˜ 있는 ì»´í¼ë„ŒíŠ¸ì™€ í´ëž˜ìŠ¤ë“¤ì„ ì‚¬ìš©í•¨ìœ¼ë¡œì¨ ë”ìš± 단순하게 만들어진 서버 ì˜ˆì œì´ë‹¤. 여기, Logging_Acceptor는 ACE_SOCK_ACCEPTOR와 Logging_Handler와 ê²°í•©ëœ ACE_Acceptor í´ëž˜ìФì´ë‹¤. ì´ê²ƒì€ ì´ì œ reactor ì¸ìŠ¤í„´ìŠ¤ë¥¼ openì‹œí‚¤ê³ ê±´ë„¤ë°›ì•„ì§„ í´ë¼ì´ì–¸íŠ¸ë¡œë¶€í„°ì˜ ì ‘ì†ì„ acceptí• ê²ƒì´ë‹¤. ë˜í•œ ACE_SigAction와 ACE_SignalHandler를 사용해서 CTRL-C를 가로채기 위해서(ì´ê²ƒì€ SIGINT를 ë°œìƒì‹œí‚¨ë‹¤) 시그ë„ì„ êµ¬í˜„í• ê²ƒì´ë‹¤. ì´ ì‹œê·¸ë„ì€ reactorê°€ ì´ë²¤íŠ¸ë¥¼ 다루는 ê²ƒì„ ë©ˆì¶”ê²Œ í•˜ëŠ”ë° ì‚¬ìš©ë 수 있다.
ì´ì œ, reactor는 CTRL+C를 사용해서 shutdownë 때까지 무한 루프를 ëŒì•„ë„ ëœë‹¤. (CTRL+C는 reactor와 acceptor 양쪽다 íŒŒê´´ëœ í›„ì— ë°œìƒí•œë‹¤)
Logging_Handler는 Event_HandlerëŒ€ì‹ ì— ACE_Svc_Handlerì—서 ìƒì†ì„ 받는다. 왜ëƒí•˜ë©´ Svc_Handler는 SOCK_Streamì„ ë‚´ìž¥í•˜ê³ ìžˆê³ reactorê°€ 요구하는 ëª¨ë“ í˜¸ì¶œì„ ì œê³µí•˜ê¸° 때문ì´ë‹¤. Svc_Handler는 ì´ë²¤íŠ¸ì— ë°˜ì‘í• ìˆ˜ 있는 ëŠ¥ë ¥ì„ ê°€ì§€ê³ ìžˆê³ ìˆ¨ê²¨ì ¸ìžˆëŠ” ë°ì´íƒ€ ìŠ¤íŠ¸ë¦¼ì„ ì‚¬ìš©í•´ì„œ 해당 업무를 ì¡°ì¢…í• ìˆ˜ 있ë„ë¡ í†µì‹ í• ìˆ˜ 있다.
timer는 아무 ê²ƒë„ í•˜ì§€ 않지만 간단하게 주기ì ì¸ ì²˜ë¦¬ê°€ í•„ìš”í• ë•Œë§ˆë‹¤ 사용ë˜ëŠ” ê²ƒì„ ë³´ì—¬ì£¼ëŠ” reactorì— ì˜í•´ 스케줄ëœë‹¤. ACE_TimeValue는 시간 주기를 ì„¤ì •í•˜ëŠ” ë° ì‚¬ìš©ëœë‹¤.
ë˜í•œ, 최ì 화는 사용한 ê°ì²´ë¥¼ 파괴해주는 별ë„ì˜ í•¨ìˆ˜ì˜ í˜•íƒœë¡œ ë§Œë“¤ì–´ì ¸ìžˆë‹¤.
ë”°ë¼ì„œ "ë”ìš± 간단한" 서버는 ì´ì œ 구축ë˜ì—ˆë‹¤. 어떻게 ìž‘ì—…ì„ ê°„ë‹¨í•˜ê²Œ 하는지를 성공ì 으로 ë³´ì—¬ì£¼ê³ , 다양한 ACE ì»´í¼ë„ŒíŠ¸ë¥¼ íŒë‹¨ì— 맞게 사용하게 ëœ ì˜ˆë¼ê³ í• ìˆ˜ 있다.
서버 ë©”ì¸ ë¶€ë¶„ 프로그램(server.cpp)ì„ ì°¾ì•„ë³´ëŠ” 것으로 시작해보ìž:
ì´ì œ, reactor는 CTRL+C를 사용해서 shutdownë 때까지 무한 루프를 ëŒì•„ë„ ëœë‹¤. (CTRL+C는 reactor와 acceptor 양쪽다 íŒŒê´´ëœ í›„ì— ë°œìƒí•œë‹¤)
Logging_Handler는 Event_HandlerëŒ€ì‹ ì— ACE_Svc_Handlerì—서 ìƒì†ì„ 받는다. 왜ëƒí•˜ë©´ Svc_Handler는 SOCK_Streamì„ ë‚´ìž¥í•˜ê³ ìžˆê³ reactorê°€ 요구하는 ëª¨ë“ í˜¸ì¶œì„ ì œê³µí•˜ê¸° 때문ì´ë‹¤. Svc_Handler는 ì´ë²¤íŠ¸ì— ë°˜ì‘í• ìˆ˜ 있는 ëŠ¥ë ¥ì„ ê°€ì§€ê³ ìžˆê³ ìˆ¨ê²¨ì ¸ìžˆëŠ” ë°ì´íƒ€ ìŠ¤íŠ¸ë¦¼ì„ ì‚¬ìš©í•´ì„œ 해당 업무를 ì¡°ì¢…í• ìˆ˜ 있ë„ë¡ í†µì‹ í• ìˆ˜ 있다.
timer는 아무 ê²ƒë„ í•˜ì§€ 않지만 간단하게 주기ì ì¸ ì²˜ë¦¬ê°€ í•„ìš”í• ë•Œë§ˆë‹¤ 사용ë˜ëŠ” ê²ƒì„ ë³´ì—¬ì£¼ëŠ” reactorì— ì˜í•´ 스케줄ëœë‹¤. ACE_TimeValue는 시간 주기를 ì„¤ì •í•˜ëŠ” ë° ì‚¬ìš©ëœë‹¤.
ë˜í•œ, 최ì 화는 사용한 ê°ì²´ë¥¼ 파괴해주는 별ë„ì˜ í•¨ìˆ˜ì˜ í˜•íƒœë¡œ ë§Œë“¤ì–´ì ¸ìžˆë‹¤.
ë”°ë¼ì„œ "ë”ìš± 간단한" 서버는 ì´ì œ 구축ë˜ì—ˆë‹¤. 어떻게 ìž‘ì—…ì„ ê°„ë‹¨í•˜ê²Œ 하는지를 성공ì 으로 ë³´ì—¬ì£¼ê³ , 다양한 ACE ì»´í¼ë„ŒíŠ¸ë¥¼ íŒë‹¨ì— 맞게 사용하게 ëœ ì˜ˆë¼ê³ í• ìˆ˜ 있다.
// $Id: ACE_c6_a9_c5_e4_b8_ae_be_f3002_2f_b4_f5_bf_ed_b0_a3_b4_dc_c7_d1_bc_ad_b9_f6,v 1.1 2004/05/20 12:24:46 redpixel Exp redpixel $
/* ì´ì „ì˜ ì˜ˆì²˜ëŸ¼, Logging_Handler를 ì„ ì–¸í•˜ëŠ”ë° ìžˆì–´ 몇가지 ACE
ê°ì²´ë“¤ì´ 필요하다. */
#include "ace/Acceptor.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/Reactor.h"
#include "handler.h"
/* 우리는 ì•„ì§ ì „ì— reactor í¬ì¸í„°ë¥¼ ì‚¬ìš©í•˜ê³ ìžˆë‹¤. ì´ê²ƒì— 대한 ì¢€ë” í†¡ì˜ëŠ”
ë°©ë²•ì€ ì°¨í›„ì˜ ì„œë²„ íŠœí† ë¦¬ì–¼ì—서 보여주ë„ë¡ í•˜ê² ë‹¤.*/
ACE_Reactor *g_reactor;
/* ì´ê²ƒì€ íŠœí† ë¦¬ì–¼ 1ì—서 힌트를 주었었다. í•˜ë“œì½”ë”©ëœ acceptor를 우리가 만들었ë˜
ê²ƒì„ ê¸°ì–µí•˜ëŠ”ê°€? ì´ í…œí”Œë¦¿ 코드는 ëª¨ë“ ì¼ì„ 해주며 ë˜ë ¤ ë” ë§Žì€ ì¼ì„ 한다.
만약 ì—¬ëŸ¬ë¶„ì˜ ì–´í”Œë¦¬ì¼€ì´ì…˜ì˜ 부분ì´ë¼ê³ ëŠê»´ì§€ì§€ì•ŠëŠ” 코드를 ë§Œë“¤ê³ ìžˆë‹¤ëŠ” 것ì„
깨달았다면, ACEê°€ ì—¬ëŸ¬ë¶„ì„ ìœ„í•´ 그런 ì¼ì„ 해줄 템플릿 ë˜ëŠ” í”„ë ˆìž„ì›Œí¬ ì»´í¼ë„ŒíŠ¸ë¥¼
ê°€ì§€ê³ ìžˆë‹¤ëŠ” ê²ƒì€ ì¢‹ì€ ì¼ì¼ 것ì´ë‹¤. */
typedef ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> Logging_Acceptor;
/* 새로 ì¶”ê°€ëœ ê²ƒë“¤ì¤‘ 하나는 ì‹œê·¸ë„ í•¸ë“¤ëŸ¬ì´ë‹¤. ì´ê²ƒì€ ê¹”ë”하게 서버가 ì¢…ë£Œí• ìˆ˜
있ë„ë¡ í•´ì¤€ë‹¤. "finished" flagì€ ì´ì „ì˜ ë¬´í•œë£¨í”„ ëŒ€ì‹ ì— ì‚¬ìš©ëœë‹¤. 그리ê³
"handler"는 SIGINT(CTRL-C)ì— ì‘답하여 ê·¸ flagì„ ì„¤ì •í•œë‹¤. {{{ACE_Reactor::notify()ì˜
ì‹¤í–‰ì€ handle_events()ê°€ return하는 결과를 만들며, "finished"ë³€ìˆ˜ì˜ ê°’ì´
ë°”ë€ ê²ƒì„ ì•Œìˆ˜ 있게 ëœë‹¤. */
static sig_atomic_t finished = 0;
extern "C" void handler (int)
{
finished = 1;
g_reactor->notify();
}
static const u_short PORT = ACE_DEFAULT_SERVER_PORT;
int
main (int, char **)
{
// ìƒì†ë°›ì€ ì´ë²¤íЏ 핸들러를 등ë¡í• reactor를 ìƒì„±í•œë‹¤.
ACE_NEW_RETURN (g_reactor, ACE_Reactor, 1);
// í´ë¼ì´ì–¸íЏ ì ‘ì†ì„ listení• acceptor를 ìƒì„±í•œë‹¤. Logging_Acceptor peer_acceptor;
/* íŠœí† ë¦¬ì–¼ 1ì˜ open()ì„ í˜¸ì¶œí•œ 것과 비슷하는 ì ì„ ì£¼ëª©í•˜ë¼. ì´ì „ 것ì„
ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n"));
// ì‹œê·¸ë„ í•¸ë“¤ëŸ¬ê°€ SIGINT를 ë°›ì„때까지 logging 서비스를 실행한다. while (!finished)
// reactorì— í• ë‹¹ëœ ë©”ëª¨ë¦¬ë¥¼ í•´ì œí•œë‹¤. delete g_reactor;
ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server logging daemon\n")); return 0;
}
// í´ë¼ì´ì–¸íЏ ì ‘ì†ì„ listení• acceptor를 ìƒì„±í•œë‹¤. Logging_Acceptor peer_acceptor;
/* íŠœí† ë¦¬ì–¼ 1ì˜ open()ì„ í˜¸ì¶œí•œ 것과 비슷하는 ì ì„ ì£¼ëª©í•˜ë¼. ì´ì „ 것ì„
ì½ì–´ë³´ê³ ì´ ë°©ë²•ìœ¼ë¡œ 하기로 했다.(-_-a 번ì—ì´...ì›ë¬¸ : I read ahead
when I created that one so that it would come out this way... */
if (peer_acceptor.open (ACE_INET_Addr (PORT), g_reactor) == -1)
ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1);
/* ì—¬ê¸°ì— ì–´í”Œë¦¬ì¼€ì´ì…˜ì— 시그ë„ë“¤ì— ì‘답하는 가장 쉬운 ë°©ë²•ì´ ìžˆë‹¤.
단순히 가로챌 시그ë„ê³¼ "C" 함수를 ê°€ì§€ê³ ACE_Sig_Actionì„
구축하면 ëœë‹¤. ì˜ˆì¸¡í–ˆê² ì§€ë§Œ, reactorì— ì‹œê·¸ë„ í•¸ë“¤ëŸ¬ë¥¼ 등ë¡í•˜ëŠ”
ë°©ë²•ë„ ë˜í•œ 존재한다. 하지만 우리는 여기서는 쉬운 방법으로 ê°€ë„ë¡
한다. */
ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT);
ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n"));
// ì‹œê·¸ë„ í•¸ë“¤ëŸ¬ê°€ SIGINT를 ë°›ì„때까지 logging 서비스를 실행한다. while (!finished)
g_reactor->handle_events ();
// acceptor를 ë‹«ì•„ ë”ì´ìƒ í´ë¼ì´ì–¸íŠ¸ë¥¼ 받아들ì´ì§€ 않는다.
peer_acceptor.close();
// reactorì— í• ë‹¹ëœ ë©”ëª¨ë¦¬ë¥¼ í•´ì œí•œë‹¤. delete g_reactor;
ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server logging daemon\n")); return 0;
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
template class ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR>;
template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#pragma instantiate ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR>
#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
}}}
3 Logging_Handler #
ì´ì œ 새로운 Logging_Handler를 ë³´ë„ë¡ í•˜ìž:
// $Id: ACE_c6_a9_c5_e4_b8_ae_be_f3002_2f_b4_f5_bf_ed_b0_a3_b4_dc_c7_d1_bc_ad_b9_f6,v 1.1 2004/05/20 12:24:46 redpixel Exp redpixel $
#ifndef LOGGING_HANDLER_H
#define LOGGING_HANDLER_H
#include "ace/INET_Addr.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/SOCK_Stream.h"
#include "ace/Reactor.h"
/* acceptor를 ìƒì„±í•˜ê¸°ìœ„í•´ í…œí”Œë¦¿ì„ ì‚¬ìš©í–ˆê¸° 때문ì—, reactorê°€ ì´ê²ƒì„
사용하게 하는 ë°©ë²•ì´ ìžˆëŠ”ì§€ 여부를 모른다. 우리는 쉬운 ë°©ë²•ì„ íƒí•˜ë„ë¡
한다. ì „ì— í¬ì¸í„° 변수를 그냥 ê°€ì ¸ì˜¨ë‹¤. (acceptorì˜ reactor로부터 다시
얻어오는 ë°©ë²•ì´ ìžˆë‹¤. ë‚˜ì¤‘ì— ì•Œì•„ë³´ë„ë¡ í•œë‹¤.) */
extern ACE_Reactor *g_reactor;
/* ì§€ê¸ˆì€ {{{ACE_Event_Handler}}}ëŒ€ì‹ ì— {{{ACE_Svc_Handlerì—서 ìƒì†
받기로 한다. ì´ë ‡ê²Œ 하는 í° ì´ìœ 는 ACE_Svc_Handlerê°€ SOCK_Streamì„
í¬í•¨í•˜ëŠ” ë²•ì„ ì•Œê³ ìžˆê³ reactorê°€ 요구하는 ëª¨ë“ ë©”ì†Œë“œ í˜¸ì¶œì„ ì œê³µí•˜ê¸°
때문ì´ë‹¤. ë‘번째 템플릿 ì¸ìžëŠ” ë‚˜ì¤‘ì— ì œìž‘í• ì„œë²„ë“¤ì—서 ì•Œë ¤ì¤„ 약간
ì–´ë ¤ìš´ 부분ì´ë‹¤. ì§€ê¸ˆì€ ê·¸ëŒ€ë¡œ ê°€ì ¸ë‹¤ ì“°ë„ë¡ í•œë‹¤. */
class Logging_Handler : public ACE_Svc_Handler <ACE_SOCK_STREAM, ACE_NULL_SYNCH>
{
public:
/* Acceptor<> í…œí”Œë¦¿ì€ ìƒˆë¡œìš´ í´ë¼ì´ì–¸íЏ ì ‘ì†ì´ ë°œìƒí• 때 open()ì„ ì‹¤í–‰í•œë‹¤. */
virtual int open (void *)
{
/* ì´ê²ƒì€ í•˜ë‚˜ì˜ ìŠ¤íƒ€ì¼ì´ê³ ì•„ë§ˆë„ ë§›ë³´ê¸°ë¼ê³ í• ìˆ˜ 있다. 소멸ìžì— ì—¬ê¸°ì— ìžˆëŠ”
/* í´ë¼ì´ì–¸íŠ¸ê°€ ì„œë²„ì™€ì˜ ì ‘ì†ì„ ì›í•˜ì§€ 않는다면, ì•„ë§ˆë„ close()를 í˜¸ì¶œí• ê²ƒì´ë‹¤.
protected:
ACE_INET_Addr addr;
/* ì ‘ì†ë˜ì–´ìžˆëŠ” í´ë¼ì´ì–¸íŠ¸ì˜ ì£¼ì†Œë¥¼ 얻기위해 peer()함수(부모í´ëž˜ìŠ¤ì— ì„ ì–¸ë˜ì–´ìžˆìŒ)
ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name ()));
return 0;
}
/* ì ‘ì†ë˜ì–´ìžˆëŠ” í´ë¼ì´ì–¸íŠ¸ì˜ ì£¼ì†Œë¥¼ 얻기위해 peer()함수(부모í´ëž˜ìŠ¤ì— ì„ ì–¸ë˜ì–´ìžˆìŒ)
를 호출한다. ì ‘ì†ì´ ëŠì–´ì¡Œì„ 때는 ì´ ë¶€ë¶„ì€ ì‹¤íŒ¨í•˜ë©°, ì•žìœ¼ë¡œì˜ ì‹¤í–‰ì„ ì¤‘ë‹¨í•œë‹¤. */
if (this->peer ().get_remote_addr (addr) == -1)
return -1;
/* Acceptor<>는 ìžì‹ ì˜ reactorì— ìžê¸°ìžì‹ ì„ ìŠ¤ìŠ¤ë¡œ 등ë¡í•˜ì§€ 않는다. 그러므로 ì´ê²ƒì€ ì†ìˆ˜
작성해주어야 한다. ì´ê²ƒì´ reactor를 ì „ì— í¬ì¸í„°ë¡œ ì„ ì–¸í•´ë‘어야하는 ì´ìœ 다. READ_MASK
를 다시 사용하는 ê²ƒì— ì£¼ëª©í•˜ìž. (그러므로 í´ë¼ì´ì–¸íŠ¸ê°€ ì–´ë–¤ ë™ìž‘ì„ í• ë•Œë§ˆë‹¤
handle_input()ê°€ 호출ëœë‹¤.) */
if (g_reactor->register_handler (this, ACE_Event_Handler::READ_MASK) == -1)
ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1);
/* ì—¬ê¸°ì— ë˜ë‹¤ë¥¸ 새로운 íŒì´ 있다. 우리는 타ì´ë¨¸ ì´ë²¤íŠ¸ë¥¼ 스케줄한다.
2초가 지나면 ë§Œê¸°ì— ë”°ë¥¸ time-out처리를 하며 다시 매 3ì´ˆí›„ì— ì‹¤í–‰ëœë‹¤.
ì´ ì˜ˆì œì•ˆì—서는 ì´ê²ƒì„ 어떻게 사용하는가를 보여주는 ê²ƒì™¸ì˜ ì–´í”Œë¦¬ì¼€ì´ì…˜ 기능ìƒì˜ 다른
ëœ»ì€ ì—†ë‹¤ëŠ” ê²ƒì„ ì•Œì•„ë‘기 바란다. */
else if (g_reactor->schedule_timer (this,
0,
ACE_Time_Value (2),
ACE_Time_Value (3)) == -1)
ACE_ERROR_RETURN ((LM_ERROR, "can'(%P|%t) t register with reactor\n"), -1);
ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name ()));
return 0;
/* ì´ê²ƒì€ í•˜ë‚˜ì˜ ìŠ¤íƒ€ì¼ì´ê³ ì•„ë§ˆë„ ë§›ë³´ê¸°ë¼ê³ í• ìˆ˜ 있다. 소멸ìžì— ì—¬ê¸°ì— ìžˆëŠ”
ëª¨ë“ ê²ƒë“¤ì„ ë„£ëŠ” 것 ëŒ€ì‹ ì—, ì´ í•¨ìˆ˜ì— ë„£ì–´ë‘ê³ "delete"를 호출하는 ëª¨ë“ ê²½ìš°ì—
destroy()를 호출한다. */
virtual void destroy (void)
{
/* reactor로 부터 ìžì‹ ì„ ì œê±°í•œë‹¤. */
g_reactor->remove_handler (this, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL);
/* 우리가 open()ì—서 스케줄한 타ì´ë¨¸ë¥¼ 취소한다. */ g_reactor->cancel_timer (this);
/* í´ë¼ì´ì–¸íŠ¸ë¡œì˜ ì—°ê²°ì„ ëŠëŠ”ë‹¤. */ this->peer ().close ();
/* ìžê¸°ìžì‹ ì˜ ë©”ëª¨ë¦¬ë¥¼ ë‚ ë¦°ë‹¤. */ delete this;
}
/* 우리가 open()ì—서 스케줄한 타ì´ë¨¸ë¥¼ 취소한다. */ g_reactor->cancel_timer (this);
/* í´ë¼ì´ì–¸íŠ¸ë¡œì˜ ì—°ê²°ì„ ëŠëŠ”ë‹¤. */ this->peer ().close ();
/* ìžê¸°ìžì‹ ì˜ ë©”ëª¨ë¦¬ë¥¼ ë‚ ë¦°ë‹¤. */ delete this;
/* í´ë¼ì´ì–¸íŠ¸ê°€ ì„œë²„ì™€ì˜ ì ‘ì†ì„ ì›í•˜ì§€ 않는다면, ì•„ë§ˆë„ close()를 í˜¸ì¶œí• ê²ƒì´ë‹¤.
ì‹¤ì œë¡œ, 만약 open()메소드ì—서 -1ì´ ë°˜í™˜ë˜ë©´ Acceptor<>는 뒷처리를 위해서 close()를
실행한다. */
virtual int close (u_long flags = 0)
{
/* ACE_Svc_Handler ë² ì´ìФ í´ëž˜ìŠ¤ëŠ” <flags> ì¸ìžë¥¼ 필요로한다. 어쨌거나 우리는 여기서
/* ì œê±°í•œ 후 사ë¼ì§„다. */ this->destroy (); return 0;
}
ê·¸ê²ƒì„ ì‚¬ìš©í•˜ì§„ 않으므로 UNUSED로 ì„¤ì •í•œë‹¤. ì†ŒìŠ¤ì•„ëž˜ì˜ handle_timeout()ì—ì„œë„ ê°™ì€ ê±¸ ë³¼ 수
ìžˆì„ ê²ƒì´ë‹¤. */
ACE_UNUSED_ARG (flags);
/* ì œê±°í•œ 후 사ë¼ì§„다. */ this->destroy (); return 0;
/* íŠœí† ë¦¬ì–¼ 1ê³¼ ê°™ì´ í´ë¼ì´ì–¸íŠ¸ë¡œë¶€í„°ì˜ ìž…ë ¥ì— ë°˜ì‘하는 함수ì´ë‹¤. */
virtual int handle_input (ACE_HANDLE)
{
/* 타ì´ë¨¸ê°€ 만기ë˜ë©´, handle_timeout()ì´ í˜¸ì¶œëœë‹¤. "arg"는
/* handle_input() (ë˜ëŠ” handle_timer())ê°€ -1ì„ ë°˜í™˜í–ˆì„ ê²½ìš° ìžê¸°ìžì‹ ì„ ì œê±°í•œë‹¤. */ virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask) {
};
char buf128;
ACE_OS::memset (buf, 0, sizeof (buf));
switch (this->peer().recv (buf, sizeof(buf)))
}
switch (this->peer().recv (buf, sizeof(buf)))
{
case -1:
return 0;
ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client logger"), -1);
case 0:
ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing log daemon (fd = %d)\n", this->get_handle ()), -1);
default:
ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s", buf));
}
/* 타ì´ë¨¸ê°€ 만기ë˜ë©´, handle_timeout()ì´ í˜¸ì¶œëœë‹¤. "arg"는
schedule_timer()í•¨ìˆ˜ì˜ ë‘번째 ì¸ìžë¡œë¶€í„° 넘어오는 ê°’ì´ë‹¤. void *
로 ì„ ì–¸ë˜ì–´ìžˆìœ¼ë¯€ë¡œ ì–´ë–¤ 변수ë¼ë„ ìºìŠ¤íŒ…í•´ì„œ 넘길 수 있다. 여기서는
단순히 메세지만 ì¶œë ¥í•˜ë„ë¡ í•œë‹¤. */
virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg)
{
ACE_UNUSED_ARG(tv);
ACE_UNUSED_ARG(arg);
ACE_DEBUG ((LM_DEBUG, "(%P|%t) handling timeout from this = %u\n", this));
return 0;
}
/* handle_input() (ë˜ëŠ” handle_timer())ê°€ -1ì„ ë°˜í™˜í–ˆì„ ê²½ìš° ìžê¸°ìžì‹ ì„ ì œê±°í•œë‹¤. */ virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask) {
this->destroy ();
return 0;
}
#endif /* LOGGING_HANDLER_H */
}}}









![[http]](/wiki/imgs/http.png)
