티스토리 툴바


포트폴리오/libSOPT2010/03/24 16:02
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
Posted by BONZOA
TAG , ,