using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace JWH.NETWORK
{

    /// <summary>
    /// AsyncSocket
    /// <para/>비동기 통신으로 개발 되었으므로, 이벤트 수신시 크로스스레드 오류가 발생할 수 있으므로 대응코드를 작성하여야 합니다.
    /// </summary>
    public class AsyncSocket : IDisposable
    {

        #region [ Events ] ====================================================
        public delegate void AsyncSocketEventHandler(AsyncSocket sender, AsyncSocketEventArgs arg);

        /// <summary>AsyncSocket Accept Event (Host)</summary>
        public event AsyncSocketEventHandler OnAccept;
        /// <summary>AsyncSocket Connect Event</summary>
        public event AsyncSocketEventHandler OnConnect;
        /// <summary>AsyncSocket Close Event</summary>
        public event AsyncSocketEventHandler OnClose;
        /// <summary>AsyncSocket Send Event</summary>
        public event AsyncSocketEventHandler OnSend;
        /// <summary>AsyncSocket Receive Event</summary>
        public event AsyncSocketEventHandler OnReceive;
        /// <summary>AsyncSocket Error Event</summary>
        public event AsyncSocketEventHandler OnError;
        #endregion

        #region [ Variable ] ==================================================
        /// <summary>Socket</summary>
        private Socket m_Socket = null;
        /// <summary>Host/Remote IPAddress</summary>
        private string m_Address = string.Empty;
        /// <summary>Port</summary>
        private int m_Port = 5000;
        /// <summary>Socket Name</summary>
        private string m_Name = string.Empty;
        #endregion

        #region [ Properties ] ================================================

        /// <summary>
        /// Socket
        /// </summary>
        public Socket Socket
        {
            get { return this.m_Socket; }
            set { this.m_Socket = value; }
        }

        /// <summary>
        /// Host/Remote IPAddress
        /// </summary>
        public string Address
        {
            get { return this.m_Address; }
            set { this.m_Address = value; }
        }

        /// <summary>
        /// Port
        /// </summary>
        public int Port
        {
            get { return m_Port; }
            set { m_Port = value; }
        }

        /// <summary>
        /// Name
        /// </summary>
        public string Name
        {
            get { return this.m_Name; }
            set { this.m_Name = value; }
        }

        /// <summary>
        /// Host 연결상태
        /// </summary>
        public bool Connected
        {
            get { return (m_Socket == null ? false : m_Socket.Connected); }
        }

        #endregion

        #region [ Constructors ] ==============================================

        /// <summary>
        /// AsyncSocket
        /// </summary>
        public AsyncSocket()
        {
        }

        /// <summary>
        /// AsyncSocket
        /// </summary>
        /// <param name="remoteAddress">Host</param>
        /// <param name="port">Port</param>
        public AsyncSocket(string remoteAddress, int port)
        {
            try
            {
                this.m_Address = remoteAddress;
                this.m_Port = port;
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        /// <summary>
        /// AsyncSocket
        /// </summary>
        /// <param name="socket">Socket</param>
        public AsyncSocket(Socket socket)
        {
            try
            {
                this.m_Socket = socket;
                try
                {
                    IPEndPoint endpoint = (IPEndPoint)this.m_Socket.RemoteEndPoint;
                    this.m_Address = endpoint.Address.ToString();
                    this.m_Port = endpoint.Port;
                }
                catch
                {
                    IPEndPoint endpoint = (IPEndPoint)this.m_Socket.LocalEndPoint;
                    this.m_Address = endpoint.Address.ToString();
                    this.m_Port = endpoint.Port;
                }

                if (this.m_Socket != null && this.m_Socket.IsBound)
                {
                    this.Receive();
                }
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        /// <summary>
        /// 구성요소를 초기화합니다
        /// </summary>
        public void InitializeComponent()
        {
            try
            {
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        /// <summary>
        /// 사용 중인 모든 리소스를 정리합니다
        /// </summary>
        public void Dispose()
        {
            try
            {
                if (m_Socket != null)
                {
                    if (m_Socket.Connected == true) this.Close();
                }
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        /// <summary>
        /// ToString
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            try
            {
                if (this.m_Socket == null) return this.Name;

                string strValue = string.Empty;
                try
                {
                    strValue = string.Format("{0}:{1}", this.m_Socket.RemoteEndPoint.ToString(), this.Name);
                }
                catch
                {
                    try
                    {
                        strValue = string.Format("{0}:{1}", this.m_Socket.LocalEndPoint.ToString(), this.Name);
                    }
                    catch { }
                }

                return strValue;
            }
            catch
            {
                return this.Name;
            }
        }

        /// <summary>
        /// 지정한 개체 인스턴스가 동일한지를 확인합니다.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            if (obj == null) return false;

            AsyncSocket temp = obj as AsyncSocket;
            if (temp == null) return false;

            if (temp.Name != this.Name) return false;
            if (temp.m_Address != this.Address) return false;
            if (temp.Port != this.Port) return false;
            if (temp.Socket != this.Socket) return false;

            return true;
        }

        /// <summary>
        /// 기본 해시 함수로 작동합니다.
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        #endregion

        #region [ Methods ] ===================================================

        #region [ Raise_Event ] -----------------------------------------------

        /// <summary>
        /// OnAccept 이벤트를 전단합니다.
        /// </summary>
        /// <param name="e"></param>
        protected virtual void Raise_OnAccept(AsyncSocketEventArgs e)
        {
            try
            {
                this.OnAccept?.Invoke(this, e);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        /// <summary>
        /// OnConnect 이벤트를 전단합니다.
        /// </summary>
        /// <param name="e"></param>
        protected virtual void Raise_OnConnect(AsyncSocketEventArgs e)
        {
            try
            {
                this.OnConnect?.Invoke(this, e);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        /// <summary>
        /// OnClose 이벤트를 전단합니다.
        /// </summary>
        /// <param name="e"></param>
        protected virtual void Raise_OnClose(AsyncSocketEventArgs e)
        {
            try
            {
                this.OnClose?.Invoke(this, e);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        /// <summary>
        /// OnSend 이벤트를 전단합니다.
        /// </summary>
        /// <param name="e"></param>
        protected virtual void Raise_OnSend(AsyncSocketEventArgs e)
        {
            try
            {
                this.OnSend?.Invoke(this, e);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        /// <summary>
        /// OnReceive 이벤트를 전단합니다.
        /// </summary>
        /// <param name="e"></param>
        protected virtual void Raise_OnReceive(AsyncSocketEventArgs e)
        {
            try
            {
                this.OnReceive?.Invoke(this, e);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        /// <summary>
        /// OnError 이벤트를 전단합니다.
        /// </summary>
        /// <param name="e"></param>
        protected virtual void Raise_OnError(AsyncSocketEventArgs e)
        {
            try
            {
                this.OnError?.Invoke(this, e);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        #endregion

        #region [ Connect ] ---------------------------------------------------

        /// <summary>
        /// Connect
        /// </summary>
        public void Connect()
        {
            try
            {
                if (this.m_Socket != null && this.m_Socket.Connected == true) return;

                IPAddress[] ipAddress = Dns.GetHostAddresses(this.m_Address);
                IPEndPoint ipEndPoint = new IPEndPoint(ipAddress[0], m_Port);
                if (this.m_Socket == null)
                {
                    this.m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    this.m_Socket.ReceiveBufferSize = AsyncObject.BUFFER_SIZE;
                }

                this.m_Socket.BeginConnect(ipEndPoint, new AsyncCallback(this.OnConnectCallback), this.m_Socket);
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
                arg.Exception = exa;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
                arg.Exception = ex;
                this.Raise_OnError(arg);
            }
        }

        /// <summary>
        /// Connect
        /// </summary>
        /// <param name="hostAddress"></param>
        /// <param name="port"></param>
        public void Connect(string hostAddress, int port)
        {
            try
            {
                if (this.m_Socket != null && this.m_Socket.Connected == true) return;

                this.m_Address = hostAddress;
                this.m_Port = port;
                this.Connect();
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                this.Raise_OnError(arg);
            }
        }

        /// <summary>
        /// Connect Callback
        /// </summary>
        /// <param name="ar"></param>
        protected void OnConnectCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                client.EndConnect(ar);

                // OnConnect 이벤트를 날린다.
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
                this.Raise_OnConnect(arg);
                this.Receive();
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                this.Raise_OnError(arg);
            }
        }

        #endregion

        #region [ Close ] -----------------------------------------------------

        /// <summary>
        /// Close
        /// </summary>
        public void Close()
        {
            try
            {
                if (this.m_Socket.Connected == true)
                {
                    this.m_Socket.Shutdown(SocketShutdown.Both);
                    this.m_Socket.BeginDisconnect(false, new AsyncCallback(OnCloseCallback), this.m_Socket);
                }
                else
                {
                    this.m_Socket.Close(100);
                    this.m_Socket = null;
                }
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                this.Raise_OnError(arg);
            }
        }

        /// <summary>
        /// Close Callback
        /// </summary>
        /// <param name="ar"></param>
        protected void OnCloseCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;

                // OnClose 이벤트를 전송한다
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
                this.Raise_OnClose(arg);

                if (client.IsBound)
                {
                    client.EndDisconnect(ar);
                    client.Close();
                }
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                this.Raise_OnError(arg);
            }
        }

        #endregion

        #region [ Send ] ------------------------------------------------------

        /// <summary>
        /// Send
        /// </summary>
        /// <param name="buffer"></param>
        public void Send(byte[] buffer, object tag = null)
        {
            try
            {
                this.m_Socket.BeginSend(buffer, 0, buffer.Length, 0, new AsyncCallback(OnSendCallback), this.m_Socket);

                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Bytes = buffer;
                arg.Tag = tag;
                this.Raise_OnSend(arg);
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                arg.Tag = tag;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                arg.Tag = tag;
                this.Raise_OnError(arg);
            }
        }

        /// <summary>
        /// Send
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="size"></param>
        public void Send(byte[] buffer, int offset, int size, object tag = null)
        {
            try
            {
                this.m_Socket.BeginSend(buffer, offset, size, 0, new AsyncCallback(OnSendCallback), this.m_Socket);

                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Bytes = buffer.Clone(offset, size);
                arg.Tag = tag;
                this.Raise_OnSend(arg);
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                arg.Tag = tag;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                arg.Tag = tag;
                this.Raise_OnError(arg);
            }
        }

        /// <summary>
        /// Send
        /// </summary>
        /// <param name="buffer"></param>
        public void Send(string buffer, object tag = null)
        {
            try
            {
                byte[] byteBuffer = Encoding.ASCII.GetBytes(buffer);
                this.m_Socket.BeginSend(byteBuffer, 0, buffer.Length, 0, new AsyncCallback(this.OnSendCallback), this.m_Socket);

                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Bytes = byteBuffer;
                arg.Tag = tag;
                this.Raise_OnSend(arg);
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                arg.Tag = tag;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                arg.Tag = tag;
                this.Raise_OnError(arg);
            }
        }

        /// <summary>
        /// Send
        /// </summary>
        /// <param name="buffer"></param>
        public void Send(string buffer, Encoding encoding, object tag = null)
        {
            try
            {
                byte[] byteBuffer = encoding.GetBytes(buffer);
                this.m_Socket.BeginSend(byteBuffer, 0, buffer.Length, 0, new AsyncCallback(this.OnSendCallback), this.m_Socket);

                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Bytes = byteBuffer;
                arg.Tag = tag;
                this.Raise_OnSend(arg);
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                arg.Tag = tag;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                arg.Tag = tag;
                this.Raise_OnError(arg);
            }
        }

        /// <summary>
        /// Send Callback
        /// </summary>
        /// <param name="ar"></param>
        protected void OnSendCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                int bytesWritten = client.EndSend(ar);
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                this.Raise_OnError(arg);
            }
        }

        #endregion

        #region [ Receive ] ---------------------------------------------------

        /// <summary>
        /// Recive
        /// </summary>
        public void Receive()
        {
            try
            {
                AsyncObject stateObject = new AsyncObject(this.m_Socket);
                this.m_Socket.BeginReceive(stateObject.Buffer, 0, AsyncObject.BUFFER_SIZE, 0, new AsyncCallback(this.OnReceiveCallback), stateObject);
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
                arg.Exception = exa;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
                arg.Exception = ex;
                this.Raise_OnError(arg);
            }
        }

        /// <summary>
        /// Receive Callback
        /// </summary>
        /// <param name="ar"></param>
        protected void OnReceiveCallback(IAsyncResult ar)
        {
            try
            {
                AsyncObject stateObject = ar.AsyncState as AsyncObject;
                Socket client = stateObject.Socket;
                int nLength = client.EndReceive(ar);

                if (nLength == 0)
                {
                    this.Close();
                    return;
                }

                // OnReceive 이벤트를 전송한다
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
                arg.Bytes = stateObject.Buffer.Clone(0, nLength);
                this.Raise_OnReceive(arg);
                this.Receive();
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                this.Raise_OnError(arg);
            }
        }

        #endregion

        #region [ Listen ] ----------------------------------------------------

        /// <summary>
        /// Listen (Host)
        /// </summary>
        /// <param name="backlog">보류 중인 연결 큐의 최대 길이입니다</param>
        public void Listen(int backlog = 100)
        {
            try
            {
                IPAddress[] ipAddress = Dns.GetHostAddresses(m_Address);
                IPEndPoint ipEndPoint = new IPEndPoint(ipAddress[0], m_Port);
                if (this.m_Socket == null)
                {
                    this.m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    this.m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                }
                this.m_Socket.Bind(ipEndPoint);
                this.m_Socket.Listen(backlog);
                this.m_Socket.BeginAccept(new AsyncCallback(this.OnAcceptCallback), this.m_Socket);
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                this.Raise_OnError(arg);
            }
        }

        /// <summary>
        /// Listen
        /// </summary>
        /// <param name="hostAddress">Host</param>
        /// <param name="port">Port</param>
        /// <param name="backlog">보류 중인 연결 큐의 최대 길이입니다</param>
        public void Listen(string hostAddress, int port, int backlog = 100)
        {
            try
            {
                this.m_Address = hostAddress;
                this.m_Port = port;
                this.Listen(backlog);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        #endregion

        #region [ Accept ] ----------------------------------------------------

        /// <summary>
        /// Accept CallBack
        /// </summary>
        /// <param name="ar"></param>
        protected void OnAcceptCallback(IAsyncResult ar)
        {
            try
            {
                if (this.m_Socket == null) return;
                Socket listener = (Socket)ar.AsyncState;
                if (!listener.IsBound) return;

                Socket client = listener.EndAccept(ar);
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
                this.Raise_OnAccept(arg);
                this.m_Socket.BeginAccept(new AsyncCallback(this.OnAcceptCallback), this.m_Socket);
            }
            catch (SocketException exa)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = exa;
                this.Raise_OnError(arg);
            }
            catch (Exception ex)
            {
                AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
                arg.Exception = ex;
                this.Raise_OnError(arg);
            }
        }

        #endregion

        #endregion

    }

    /// <summary>
    /// AsyncSocket Event Argument
    /// </summary>
    public class AsyncSocketEventArgs : EventArgs
    {

        #region [ Variable ] ==================================================
        /// <summary>Socket</summary>
        private Socket m_Socket = null;
        /// <summary>Send/Receive Data</summary>
        private byte[] m_Bytes = null;
        /// <summary>Tag</summary>
        private object m_Tag = null;
        /// <summary>Exception</summary>
        private Exception m_Exception = null;
        #endregion

        #region [ Properties ] ================================================

        /// <summary>
        /// Socket
        /// </summary>
        public Socket Socket
        {
            get { return this.m_Socket; }
            set { this.m_Socket = value; }
        }

        /// <summary>
        /// Send/Receive Data
        /// </summary>
        public byte[] Bytes
        {
            get { return this.m_Bytes; }
            set { this.m_Bytes = value; }
        }

        /// <summary>
        /// Exception
        /// </summary>
        public Exception Exception
        {
            get { return this.m_Exception; }
            set { this.m_Exception = value; }
        }

        /// <summary>
        /// Tag
        /// </summary>
        public object Tag
        {
            get { return this.m_Tag; }
            set { this.m_Tag = value; }
        }

        #endregion

        #region [ Constructors ] ==============================================

        /// <summary>
        /// 생성자
        /// </summary>
        public AsyncSocketEventArgs()
        {
        }

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="socket">Socket</param>
        public AsyncSocketEventArgs(Socket socket)
        {
            m_Socket = socket;
        }

        #endregion

    }

    /// <summary>
    /// 비동기 작업의 상태
    /// </summary>
    public class AsyncObject
    {

        #region [ Variables ] =================================================
        /// <summary>버퍼사이즈</summary>
        public static int BUFFER_SIZE = 32768;
        /// <summary>Socket</summary>
        private Socket m_Socket;
        /// <summary>Buffer</summary>
        private byte[] m_byteBuffer;
        #endregion

        #region [ Properties ] ================================================

        /// <summary>
        /// Socket
        /// </summary>
        public Socket Socket
        {
            get { return this.m_Socket; }
            set { this.m_Socket = value; }
        }

        /// <summary>
        /// 버퍼
        /// </summary>
        public byte[] Buffer
        {
            get { return this.m_byteBuffer; }
            set { this.m_byteBuffer = value; }
        }

        #endregion

        #region [ Constructors ] ==============================================

        /// <summary>
        /// AsyncObject
        /// </summary>
        /// <param name="socket">Socket</param>
        public AsyncObject(Socket socket)
        {
            try
            {
                this.m_Socket = socket;
                this.m_byteBuffer = new byte[BUFFER_SIZE];
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        #endregion

    }
}
