1. 개요
Stream_Handler 신규 서비스 요청에 대한 종단점를 나타내는 클래스.
신규 서비스 요청의 인증이 완료된 이후 Accepor의 make_handler 메소드를 통해 생성되며, 신규 서비스 요청에 대한 종단점(이하, 클라이언트)를 처리하기 위한 클래스입니다.
클라이언트와의 메세지 송수신은 asynchronously I/O를 이용하도록 디자인되었습니다. Windows에서는 IOCP를 이용한 Proactor 패턴이 사용되며, POSIX 호환 플랫폼에서는 POSIX Realtime signal 을 이용한 io control block을 사용되여 Proactor 패턴이 구현됩니다.
Stream_Handler는 일반적으로 Request_Handler와 함께 사용되어야 합니다. Request_Handler는 클라이언트로부터 전송되어오는 데이터를 사용하기 편리하도록 캡슐화합니다.
Request_Handler가 올바르게 수신되었다면, Executor로 Stream_Handler와 함께 전달됩니다.
클라이언트의 예기치 않은 종료로 인해, 이미 Executor로 전달된 task에서 발생될수 있는 예외의 올바른 처리를 위해 RefCount기법을 이용합니다.
즉, 클라이언트와의 연결은 종료되지만 Stream_Handler 객체의 소멸은 Executor에 존재하는 해당 Stream_Handler가 모두 처리될때까지 지연됩니다.
2. Stream_Handler의 선언은 다음과 같습니다.
// -*- C++ -*-
//=============================================================================
/**
* @file stream_handler.h
*
* $Id: stream_handler.h Fri Mon 16 17:23:23 GMT+09:00 2009
*
* @author Copyright 2008-2009 SOPT(Shout Our Passion Together)
*/
//=============================================================================
#ifndef _STREAM_HANDLER_DEFINE
#define _STREAM_HANDLER_DEFINE
#if !defined (ACE_LACKS_PRAGMA_ONCE)
#pragma once
#endif
#include "ace/Synch.h"
#include "ace/Asynch_IO.h"
#include "ace/INET_Addr.h"
#include "ace/Refcountable.h"
#if defined(ACE_WIN32)
#include "sopt_export.h"
#elif
typedef SOPT_Export ACE_Export
#endif
namespace libsopt {
class Server;
class Request_Handler;
/**
* @class Stream_Handler
*
* @brief Stream_Handler 신규 서비스 요청에 대한 종단점를 나타내는 클래스.
*
* 신규 서비스 요청의 인증이 완료된 이후 Accepor의 make_handler 메소드를 통해 생성되며,
* 신규 서비스 요청에 대한 종단점(이하, 클라이언트)를 처리하기 위한 클래스입니다.
*
* 클라이언트와의 메세지 송수신은 asynchronously I/O를 이용하도록 디자인되었습니다.
* Windows에서는 IOCP를 이용한 Proactor 패턴이 사용되며, POSIX 호환 플랫폼에서는 POSIX Realtime signal
* 을 이용한 io control block을 사용되여 Proactor 패턴이 구현됩니다.
*
* Stream_Handler는 일반적으로 Request_Handler와 함께 사용되어야 합니다.
* Request_Handler는 클라이언트로부터 전송되어오는 데이터를 사용하기 편리하도록 캡슐화합니다.
*
* Request_Handler가 올바르게 수신되었다면, Executor로 Stream_Handler와 함께 전달됩니다.
*
* 클라이언트의 예기치 않은 종료로 인해, 이미 Executor로 전달된 task에서 발생될수 있는 예외의 올바른 처리를 위해
* RefCount기법을 이용합니다.
*
* 즉, 클라이언트와의 연결은 종료되지만 Stream_Handler 객체의 소멸은 Executor에 존재하는 해당 Stream_Handler가
* 모두 처리될때까지 지연됩니다.
*/
class SOPT_Export Stream_Handler :
public ACE_Service_Handler,
public ACE_Refcountable {
protected :
/// Stream_Handler를 생성한 Server 객체에 대한 포인터
Server *serv_;
ACE_Asynch_Read_Stream reader_;
ACE_Asynch_Write_Stream writer_;
ACE_Thread_Mutex guard_;
ACE_INET_Addr remote_address_;
int closemark_;
int read_shutdown_;
int write_shutdown_;
void shutdown(int sd_type);
void abortive_close();
/// 클라이언트와의 연결을 종료합니다.
/// 연결이 종료된 후, Server로 연결종료를 통지합니다.
void connection_close();
public :
/// 기본생성자
explicit Stream_Handler()
: ACE_Refcountable(0), closemark_(1), read_shutdown_(0), write_shutdown_(0)
{ /* empty */ }
/// 기본소멸자.
/// 클라이언트와의 연결이 유효하다면 연결을 종료합니다.
virtual ~Stream_Handler();
/**
* 신규 서비스 요청의 인증이 완료된 이후 Accepor의 make_handler 메소드를 통해 생성된 직후,
*
* @param new_handle 신규 종단점애 대한 핸들러
* @param message_block 사용되지 않음
*/
virtual void open(ACE_HANDLE new_handle, ACE_Message_Block &message_block);
/**
* Executor에 전달되기 전에, RefCount를 1증가 합니다.
*
* @retval Stream_Handler * this 포인터
*/
Stream_Handler * shallow_copy();
/**
* Stream_Handler의 RefCount를 1감소 합니다.
* RefCount가 0이 된다면 해당 객체를 소멸시킵니다.
* 또한, closemark_ 필드를 확인하여, 클라이언트와의 연결을 종료할수 있습니다.
*/
void clear();
/**
* 예기치 않은 오류나, call 메소드의 부정확한 실행결과, 기타상황으로 인해
* 클라이언트와의 연결을 종료해야 한다면 0이 아닌 값으로 mark를 전달합니다.
*
* @param mark mark가 0이 아닌 값이라먄, clear메소드 호출시 해당 클라이언트와의 연결을 종료합니다.
*/
void closemark(int mark);
/// closemark_ 필드의 값을 반환합니다.
int closemark();
/**
* 클라이언트의 핸들의 유효성을 검증합니다.
*
* @retval 0 클라이언트 핸들이 유효하지 않습니다.
* @retval 1 클라이언트의 핸들이 유요합니다.
*/
int has_valid_handle();
/**
* how에 의해 결정되는 클라이언트와의 연결상태를 검증합니다.
*
* @param how
* - ACE_SHUTDOWN_READ
* - ACE_SHUTDOWN_WRITE
* - ACE_SHUTDOWN_BOTH
*
* @retval 0 클라이언트와의 연결이 유효하지 않습니다.
* @retval 1 클라이언트와의 연결이 유요합니다.
*/
int is_connected(int how);
/**
* Request_Handler의 Header를 수신을 바인딩합니다.
*
* @retval 0 바인딩을 성공했습니다.
* @retval -1 바인딩을 실패했습니다.
*/
int handle_read_header();
/**
* Request_Handler의 Payload를 수신을 바인딩합니다.
*
* @param r Header 수신을 완료한 Request_Handler 입니다.
*
* @retval 0 바인딩을 성공했습니다.
* @retval -1 바인딩을 실패했습니다.
*/
int handle_read_payload(Request_Handler *r);
/**
* synchronously send
*
* @param write_mb 전송할 메세지
* @param length 전송할 메세지의 길이
*/
void synch_write_n(ACE_Message_Block *write_mb, ssize_t length);
/**
* asynchronously send의 작업 완료통지 메소드
*
* @param write_mb 전송할 메세지
* @param length 전송할 메세지의 길이
*/
void asynch_write_n(ACE_Message_Block *write_mb, ssize_t length);
/// 신규종단점에 대한 IPv4주소를 수집합니다.
virtual void
addresses(const ACE_INET_Addr &remote_address, const ACE_INET_Addr &local_address);
/**
* asynchronously read의 작업 완료통지 메소드
*
* @param result 작업완료에 대한 결과정보
*/
virtual void
handle_read_stream(const ACE_Asynch_Read_Stream::Result &result);
/**
* asynchronously write의 작업 완료통지 메소드
*
* @param result 작업완료에 대한 결과정보
*/
virtual void
handle_write_stream(const ACE_Asynch_Write_Stream::Result &result);
/// 클라이언트의 IPv4 주소를 문자열로 반환합니다.
const char * remote_addr_by_string();
/// 클라이언트의 IPv4 주소를 32bit 정수형으로 반환합니다.
ACE_UINT32 remote_addr_by_integer();
/// 클라이언트의 포트번호를 반환합니다.
u_short remote_port();
/// return serv_;
Server * Stream_Handler::server() const
{ return serv_; }
/// serv_ = serv;
void Stream_Handler::server(Server *serv)
{ serv_ = serv; }
};
};
#endif
'포트폴리오 > libSOPT' 카테고리의 다른 글
| libSOPT다운로드 (0) | 2010/03/24 |
|---|---|
| libSOPT기반 echo server (0) | 2010/03/24 |
| libSOPT::Server (0) | 2010/03/24 |
| libSOPT::Executor (0) | 2010/03/24 |
| libSOPT::Request_Handler (0) | 2010/03/24 |
| libSOPT::Stream_Handler (0) | 2010/03/24 |
| libSOPT::Acceptor (0) | 2010/03/24 |
| libSOPT 소개 (0) | 2010/03/24 |
