/*!
	CIPv4ListenerBase

	IPv4用系接続受付クラスの基本クラス
*/

#pragma once
#include "ThreadSkeleton.h"
#include "ListenSocket.h"
#include "IListener.h"
#include "IServerToolWrap.h"
#include "Settings.h"

/*!
	IPv4用系接続受付クラスの基本クラス
*/
class CIPv4ListenerBase :
	private CThreadSkeleton
{
public:
	CIPv4ListenerBase(void);
	virtual ~CIPv4ListenerBase(void);

protected:
	/////////////////////////////////////////////////////////////////////////////////////
	//	オーバーロード
	/////////////////////////////////////////////////////////////////////////////////////
	//!	クラス名取得
	virtual LPCU8STR GetListenerClassName() = 0;

	//!	接続追加
	virtual void OnNewConnection(SOCKET newSock) = 0;

	/////////////////////////////////////////////////////////////////////////////////////
	//	操作
	/////////////////////////////////////////////////////////////////////////////////////
	//!	初期化
	void InitListenerBase(CIServerToolWrap serverTool, int errorRetryTime);

	//!	開始
	void StartListenerBase();

	//!	停止
	void StopListenerBase();

	//!	設定からポート追加
	void AddPortsFromSetting(CUTF8String strPorts);

	//!	ポートの追加
	void AddPort(int port);

	//!	ポート数取得
	int GetPortCount() { return m_listeners.GetCount(); };

	//!	一時的に受け付け停止
	void ForceDisableNewConnection(int time);

private:
	/////////////////////////////////////////////////////////////////////////////////////
	//	スレッド関数
	/////////////////////////////////////////////////////////////////////////////////////
	//!	スレッド
	void ThreadMain();

	//!	クリーンアップ
	void CloseAllPorts();

	//!	受付ループ
	int AcceptLoop();

	//!	ポートを開く
	int OpenPorts();

	//!	ポートを閉じる
	void ClosePorts();

	//!	接続を受け付け
	int AcceptConnections();

	//!	接続が来るのを待つ
	void WaitNextRequest();

	//!	停止中？
	int InDisableMode();

	/////////////////////////////////////////////////////////////////////////////////////
	//	メンバ変数
	/////////////////////////////////////////////////////////////////////////////////////
	//!	サーバツール
	CIServerToolWrap						m_serverTool;

	//!	リスナ配列
	CPtrArrayTemplate<CListenSocket*>		m_listeners;

	//!	エラーリトライ時間
	int										m_errorRetryTime;

	//!	受付無効終了予定
	DWORD									m_disableNewConnectionEndTime;
};
