using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using SystemX.Common;
using SystemX.Common.Serialization;
using SystemX.Net.Comm;

//using static SystemX.Net.Platform.Common.Util.LogMessage;

namespace SystemX.Net.Comm
{
    public class AsyncServerSocket : SystemXSocket, IDisposable
    {
        private Socket ServerSock;

        private IPAddress SetAddress;

        //Unused
        private Socket ClientSock;      /* client Socket */
        //private Socket cbClientSock;    /* client Async Callback Socket */

        private byte[] recvBuffer;
        //private String recvText;

        private byte[] recvStoreBuffer;
        private int iStoreCnt;
        private int iCheckRetryCnt;

        private const int MAX_CHECK_COUNT = 100;        /* 256000 / 4096 <- 65526 / 4096 */
        private const int USER_MAX_SIZE = 819200;      /* 256000 <- 1000000 65536 */
        private const int MAXSIZE = 8192;               /* 8192 <- 4096  */

        private string m_strGetIp;
        private int m_iGetPort;

        private bool m_bOpen;
        private bool m_bConnected;

        private string m_strGetText;
        private bool m_bGetRecv;

        public override event SocketCallEvent Comm_Connect_Event;
        public override event SocketCallEvent Socket_Error_Event;

        public override event SendRecvCallEvent Comm_Send_Event;
        public override event SendRecvCallEvent Comm_Recv_Event;

        private Queue<CPacketDataInfo> QPacketAllData;
        private Queue<CPacketDataInfo> QPacketRemainData;

        private bool bQueuePacketClearOn;

        public override void SetRefSocketPacketClear()
        {
            bQueuePacketClearOn = true;
        }

        private bool bDisposed;

        //
        //private bool bHaveHostinfo;
        //private DataTable dtHostInfo;

        public bool STATE
        {
            get { return this.m_bOpen; }
        }
        public bool CLIENT_CONNECT
        {
            get { return this.m_bConnected; }
        }
        public string MSG
        {
            set { this.m_strGetText = value; }
            get { return this.m_strGetText; }
        }
        public bool RECV_STATE
        {
            set { this.m_bGetRecv = value; }
            get { return this.m_bGetRecv; }
        }

        public string strSetRemoteAddress { set; get; }
        public string strSetRemotePort { set; get; }

        /*
        public bool HAVE_HOST_INFO
        {
            set { this.bHaveHostinfo = value; }
            get { return this.bHaveHostinfo; }
        }
        */

        public AsyncServerSocket(SOCKET_TYPE SOCK_TYPE, int iCreatePosition, IPEndPoint SetRemote) : base(SOCKET_RULE.SERVER, SOCK_TYPE)
        {
            bDisposed = false;

            QPacketAllData = new Queue<CPacketDataInfo>();
            QPacketRemainData = new Queue<CPacketDataInfo>();

            bQueuePacketClearOn = false;

            strSetRemoteAddress = string.Empty;
            strSetRemotePort = string.Empty;

            SetAddress = SetRemote.Address;

            nSocketNumber = iCreatePosition;

            m_strGetIp = SetRemote.Address.ToString();
            m_iGetPort = SetRemote.Port;

            ServerSock = null;

            ClientSock = null;
            //cbClientSock = null;

            //recvText = string.Empty;
            recvStoreBuffer = new byte[USER_MAX_SIZE];
            iStoreCnt = 0;
            iCheckRetryCnt = 0;

            recvBuffer = new byte[MAXSIZE];
            //
            m_bGetRecv = false;

            m_bOpen = false;
            m_bConnected = false;

            SetSocketListen();
        }

        public AsyncServerSocket(SOCKET_TYPE SOCK_TYPE, int iCreatePosition, IPEndPoint SetRemote, DataTable dtHostInfomation) : base(SOCKET_RULE.SERVER, SOCK_TYPE)
        {
            bDisposed = false;

            strSetRemoteAddress = string.Empty;
            strSetRemotePort = string.Empty;

            SetAddress = SetRemote.Address;

            nSocketNumber = iCreatePosition;

            m_strGetIp = SetRemote.Address.ToString();
            m_iGetPort = SetRemote.Port;

            ServerSock = null;
            ClientSock = null;
            //cbClientSock = null;

            //recvText = string.Empty;
            recvStoreBuffer = new byte[USER_MAX_SIZE];
            iStoreCnt = 0;
            iCheckRetryCnt = 0;

            recvBuffer = new byte[MAXSIZE];
            //
            m_bGetRecv = false;

            m_bOpen = false;
            m_bConnected = false;

            SetSocketListen();
        }

        protected override void Dispose(bool disposing)
        {
            if (!bDisposed)
            {
                ConnectTokken.SetTokenState((ConnectTokken.Connect_Token)nSocketNumber, false);

                try
                {
                    if (ServerSock != null)
                    {
                        if (ServerSock.Connected)
                            ServerSock.Shutdown(SocketShutdown.Both);

                        ServerSock.Close();
                        //ServerSock.Dispose();
                        ServerSock = null;
                    }

                    m_bOpen = false;

                    ClientSock = null;

                    m_bConnected = false;
                }
                catch (Exception e)
                {
                    ClientSock = null;

                    ServerSock = null;

                    m_bOpen = false;

                    m_bConnected = false;

                    ErrorEventProcess(new Exception("Dispose failed. [SystemX.Net.Comm : AsyncServerSocket.Dispose]"));
                }
                finally
                {
                    /*
                    ClearEventConnectCall();
                    ClearEventErrorCall();
                    */

                    ClearEventSendCall();
                    ClearEventRecvCall();
                }

                if (disposing)
                {
                    //Manage
                }

                //Unmanage
                recvStoreBuffer = null;
                recvBuffer = null;

                bDisposed = true;
            }

            //Base Dispose
            base.Dispose(disposing);
        }

        public void ClearEventConnectCall()
        {
            if (Comm_Connect_Event != null)
            {
                foreach (Delegate d in Comm_Connect_Event.GetInvocationList())
                    Comm_Connect_Event -= (SocketCallEvent)d;
            }
        }

        public void ClearEventErrorCall()
        {
            if (Socket_Error_Event != null)
            {
                foreach (Delegate d in Socket_Error_Event.GetInvocationList())
                    Socket_Error_Event -= (SocketCallEvent)d;
            }
        }

        public void ClearEventSendCall()
        {
            if (Comm_Send_Event != null)
            {
                foreach (Delegate d in Comm_Send_Event.GetInvocationList())
                    Comm_Send_Event -= (SendRecvCallEvent)d;
            }
        }

        public void ClearEventRecvCall()
        {
            if (Comm_Recv_Event != null)
            {
                foreach (Delegate d in Comm_Recv_Event.GetInvocationList())
                    Comm_Recv_Event -= (SendRecvCallEvent)d;
            }
        }

        public void ServerSocketAllClearToken()
        {
            ConnectTokken.AllClearToken((ConnectTokken.Connect_Token)nSocketNumber);
        }

        public bool ServerTokenPosCheck(int iGet)
        {
            return ConnectTokken.GetTokenPosState((ConnectTokken.Connect_Token)nSocketNumber, iGet);
        }

        public void ServerSocketUnknownError(bool bCallEvent = true)
        {
            ConnectTokken.SetTokenState((ConnectTokken.Connect_Token)nSocketNumber, false);

            try
            {
                if (ClientSock != null)
                {
                    if (ClientSock.Connected)
                    {
                        ClientSock.Disconnect(false);
                        ClientSock.Shutdown(SocketShutdown.Both);

                        ClientSock.Close();
                        ClientSock = null;
                    }

                    ClientSock = null;
                }

                //m_bOpen = false;
            }
            catch (Exception ex)
            {
                ClientSock = null;

                //MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"Client socket release error.[SystemX.Net.Net.Comm.AsyncServerSocket] " + ex.Message, ConsoleColor.Yellow, LogMessageLevel.DEBUG);
            }

            m_bConnected = false;

            if (bCallEvent)
                Socket_Error_Event?.Invoke(null, new ScheduleEvent(nSocketNumber, false, "Error", 0));
        }
        private void ErrorEventProcess(Exception e, bool ConnectStateOff = false, bool bServerSock = false)
        {
            //if (e.SocketErrorCode == SocketError.NotConnected)
            ConnectTokken.SetTokenState((ConnectTokken.Connect_Token)nSocketNumber, false);

            if (bServerSock == false)
                m_bConnected = ConnectStateOff;
            else
                m_bOpen = ConnectStateOff;

            Socket_Error_Event?.Invoke(e, new ScheduleEvent(nSocketNumber, false, "Error", 0));
        }
        private void AcceptCallback(IAsyncResult ar)
        {
            try
            {
                if (m_bOpen)
                {
                    Socket SockListen = null;

                    try
                    {
                        SockListen = (Socket)ar?.AsyncState;

                        int nGetAvailable = SockListen.Available;
                    }
                    catch (ObjectDisposedException dispose)
                    {
                        SockListen = null;

                        throw new Exception();
                    }

                    if (SockListen != null)
                    {
                        IPEndPoint GetIPInfo = (IPEndPoint)SockListen.LocalEndPoint;

                        if (ConnectTokken.GetTokenState((ConnectTokken.Connect_Token)nSocketNumber) == false)
                        {
                            ConnectTokken.SetTokenState((ConnectTokken.Connect_Token)nSocketNumber, true);

                            //AsyncSocketObject objScoket = new AsyncSocketObject(MAXSIZE);

                            Socket sockClient = SockListen.EndAccept(ar);

                            //objScoket.WorkSocket = sockClient;
                            ClientSock = sockClient; // objScoket.WorkSocket;

                            m_bConnected = true;

                            sockClient.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), ClientSock);

                            Comm_Connect_Event?.BeginInvoke(ClientSock, new ScheduleEvent(nSocketNumber, true, "Connect", 0), InvokeCallback, null);
                        }

                        //클라이언트의 연결 요청 대기
                        SockListen.BeginAccept(AcceptCallback, SockListen);
                    }
                }
            }
            catch (Exception e)
            {
                //종료 또는 Accept 실패.
                ErrorEventProcess(new CommonSocketException("Middleware server side connection lost.[SystemX.Net.Comm : AsyncServerSocket|AcceptCallback]"));
            }
        }


        private void InvokeCallback(object obj)
        {
        }


        private void SetSocketListen()
        {
            try
            {
                if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
                {
                    ServerSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);

                    LingerOption SetLinger = new LingerOption(true, 0);
                    ServerSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, SetLinger);
                    //ServerSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);

                    var option = new TcpKeepAlive
                    {
                        OnOff = 1,
                        KeepAliveTime = 90000,
                        KeepAliveInterval = 3000
                    };

                    int iState = ServerSock.IOControl(IOControlCode.KeepAliveValues, option.GetBytes(), null);

                    // 서버에서 클라이언트의 연결 요청을 대기하기 위해 소켓을 열어둔다.
                    IPEndPoint mkServerEP;
                    mkServerEP = new IPEndPoint(SetAddress, m_iGetPort);

                    ServerSock.Bind(mkServerEP);
                    ServerSock.Listen(1024);

                    SetSocketBeginReady();
                }
                else if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
                {
                    ServerSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

                    // 서버에서 클라이언트의 연결 요청을 대기하기 위해 소켓을 열어둔다.
                    IPEndPoint mkServerEP;
                    mkServerEP = new IPEndPoint(SetAddress, m_iGetPort);

                    EndPoint ServerEP;
                    ServerEP = new IPEndPoint(SetAddress, m_iGetPort);

                    ServerSock.Bind(mkServerEP);

                    //ServerSock.BeginReceiveFrom(recvBuffer, 0, MAXSIZE, SocketFlags.None, ref ServerEP, new AsyncCallback(OnReceiveCallBack), ServerSock);

                    ServerSock.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), ServerSock);
                }

                m_bOpen = true;
            }
            catch (Exception e)
            {
                //종료 또는 Accept 실패.
                ErrorEventProcess(new CommonSocketException("Server socket open-ready fail.[SystemX.Net.Comm : AsyncServerSocket|DoInit]"), false, true);
            }
        }

        private void SetSocketBeginReady()
        {
            try
            {
                if (ServerSock != null)
                    // 비동기적으로 클라이언트의 연결 요청을 받는다.
                    ServerSock.BeginAccept(AcceptCallback, ServerSock);
            }
            catch (Exception e)
            {
                //종료 또는 Accept 실패.
                ErrorEventProcess(new CommonSocketException("Server socket BeginAccept() fail. [SystemX.Net.Comm : AsyncServerSocket|SetSocketListen]"), false, true);
            }
        }


        public override bool BeginSend(byte[] ucDatas)
        {
            bool bState = true;

            if (ClientSock == null)
            {
                if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
                    return false;
                else
                {
                    if (ServerSock == null)
                        return false;
                }
            }

            try
            {
                if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
                {
                    /* 연결 성공시 */
                    if (ClientSock.Connected) ClientSock.BeginSend(ucDatas, 0, ucDatas.Length, SocketFlags.None, new AsyncCallback(SendCallBack), ucDatas);
                }
                else if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
                {
                    if (strSetRemoteAddress.Length > 0 && strSetRemotePort.Length > 0)
                    {
                        EndPoint setRemote = new IPEndPoint(IPAddress.Parse(strSetRemoteAddress), int.Parse(strSetRemotePort));
                        ServerSock.BeginSendTo(ucDatas, 0, ucDatas.Length, SocketFlags.None, setRemote, new AsyncCallback(SendCallBack), ucDatas);
                    }
                }
            }
            catch (Exception e)
            {
                bState = false;

                //전송 에러
                ErrorEventProcess(e);
            }

            return bState;
        }
        public override bool BeginSend(Socket SetSock, byte[] ucDatas)
        { 
            bool bState = true;

            if (SetSock == null)
            {
                if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
                    return false;
                else
                {
                    if (ServerSock == null)
                        return false;
                }
            }

            try
            {
                /* 연결 성공시 */
                if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
                {
                    if (SetSock.Connected) SetSock.BeginSend(ucDatas, 0, ucDatas.Length, SocketFlags.None, new AsyncCallback(SendCallBack), ucDatas);
                }
                else if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
                {
                    if (strSetRemoteAddress.Length > 0 && strSetRemotePort.Length > 0)
                    {
                        EndPoint setRemote = new IPEndPoint(IPAddress.Parse(strSetRemoteAddress), int.Parse(strSetRemotePort));
                        ServerSock.BeginSendTo(ucDatas, 0, ucDatas.Length, SocketFlags.None, setRemote, new AsyncCallback(SendCallBack), ucDatas);
                    }
                }
            }
            catch (Exception e)
            {
                bState = false;

                //전송 에러
                ErrorEventProcess(e);
            }

            return bState;
        }
        public override bool BeginSend(string strMessage)
        {
            bool bState = true;

            if (ClientSock == null)
            {
                if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
                    return false;
                else
                {
                    if (ServerSock == null)
                        return false;
                }
            }

            try
            {
                byte[] buffer = new UnicodeEncoding().GetBytes(strMessage);

                /* 연결 성공시 */
                if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
                {
                    if (ClientSock.Connected) ClientSock.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendCallBack), strMessage);
                }
                else if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
                {
                    if (strSetRemoteAddress.Length > 0 && strSetRemotePort.Length > 0)
                    {
                        EndPoint setRemote = new IPEndPoint(IPAddress.Parse(strSetRemoteAddress), int.Parse(strSetRemotePort));
                        ServerSock.BeginSendTo(buffer, 0, buffer.Length, SocketFlags.None, setRemote, new AsyncCallback(SendCallBack), strMessage);
                    }
                }
            }
            catch (Exception e)
            {
                bState = false;

                //전송 에러
                ErrorEventProcess(e);
            }

            return bState;
        }
        private void SendCallBack(IAsyncResult IAR)
        {
            //전송 완료
            byte[] getData = null;
            ScheduleEvent se = new ScheduleEvent(nSocketNumber, false, "Send Fail", 0);

            if (ClientSock == null)
            {
                if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
                    return;
                else
                {
                    if (ServerSock == null)
                        return;
                }
            }

            bool bResult = true;
            try
            {
                getData = (byte[])IAR.AsyncState;

                if (getData != null)
                    se = new ScheduleEvent(nSocketNumber, true, "Send Success", 0);
                else
                    se = new ScheduleEvent(nSocketNumber, false, "Send Fail", 0);
            }
            catch (Exception e)
            {
                bResult = false;

                //Callback Error
                ErrorEventProcess(e);
            }
            finally
            {
                if (bResult)
                {
                    Comm_Send_Event?.BeginInvoke(getData, se, null, null);
                }
            }
            //
            try
            {
                int iSendCnt = 0;

                if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
                    iSendCnt = ClientSock.EndSend(IAR);
                else
                    iSendCnt = ServerSock.EndSend(IAR);
            }
            catch (Exception e)
            {
                bResult = false;

                //Callback Error
                ErrorEventProcess(e);
            }
        }

        private void Receive()
        {
            if (ClientSock == null)
            {
                if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
                    return;
                else
                {
                    if (ServerSock == null)
                        return;
                }
            }

            //받기
            try
            {
                if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
                    ServerSock.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), ServerSock);
                else
                {
                    if (ClientSock.Connected)
                        ClientSock.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), ClientSock);
                }
            }
            catch (Exception e)
            {
                ErrorEventProcess(e);
            }
        }
        private void OnReceiveCallBack(IAsyncResult IAR)
        {
            bool bReceiveState = true;
            int nReadSize = 0;

            Socket ClientSideSock;
            //AsyncSocketObject objScoket = null;

            try
            {
                //수신
                ClientSideSock = (Socket)IAR.AsyncState;
                //objScoket = (AsyncSocketObject)IAR.AsyncState;
            }
            catch (Exception e)
            {
                this.Dispose();

                //수신 실패
                ErrorEventProcess(new CommonSocketException("Middleware server side connection lost.[SystemX.Net.Comm : AsyncServerSocket|OnReceiveCallBack]"));

                return;
            }
            try
            {
                if (ClientSideSock.Connected)
                    nReadSize = ClientSideSock.EndReceive(IAR);
                else
                {
                    if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
                        nReadSize = ClientSideSock.EndReceive(IAR);
                    else
                        bReceiveState = false;
                }
            }
            catch (Exception e)
            {
                bReceiveState = false;
            }
            //
            if (bReceiveState)
            {
                if (nReadSize != 0)
                {
                    byte[] ucFindData = new byte[1];
                    byte[] ucSetClearArray;

                    int iFindDataCnt = 0;

                    bool bSegmentFind = false;
                    bool bDataFind = false;

                    byte ucGetLabel = 0;

                    try
                    {
                        /*
                        Array.Copy(recvBuffer, 0, recvStoreBuffer, iStoreCnt, nReadSize);

                        iStoreCnt += nReadSize;
                        */

                        if(bQueuePacketClearOn)
                        {
                            bQueuePacketClearOn = false;

                            QPacketAllData.Clear();
                        }

                        QPacketAllData.Enqueue(new CPacketDataInfo(DateTime.Now, recvBuffer, nReadSize));

                        foreach (var n in QPacketAllData.ToList())
                        {
                            TimeSpan dsInterval = DateTime.Now - n.dtPacket;

                            //오랜된 패킷 소거
                            if (dsInterval.TotalSeconds >= 20.0)
                                QPacketAllData.Dequeue();
                            else
                                QPacketRemainData.Enqueue(new CPacketDataInfo(n.ID, n.dtPacket, n.ucData, n.nDataSize));
                        }
                        //
                        iStoreCnt = 0;
                        Array.Clear(recvStoreBuffer, 0, USER_MAX_SIZE);

                        Guid[] guidUsePacketID = new Guid[QPacketRemainData.Count];
                        int nPacketPos = 0;

                        //남은 패킷중 연산 시도
                        foreach (var n in QPacketRemainData.ToList())
                        {
                            Array.Copy(n.ucData, 0, recvStoreBuffer, iStoreCnt, n.nDataSize);

                            iStoreCnt += n.nDataSize;

                            guidUsePacketID[nPacketPos++] = n.ID;

                            for (int j = 0; j < iStoreCnt; j++)
                            {
                                if (recvStoreBuffer[j] == 0x0D &&
                                    recvStoreBuffer[j + 1] == 0x02 &&
                                    recvStoreBuffer[j + 6] == 0x08 &&
                                    recvStoreBuffer[j + 7] == 0x0A)
                                {
                                    ucGetLabel = recvStoreBuffer[j - 1];

                                    uint uiGetPacketSize = 0x0;

                                    uiGetPacketSize |= (uint)(recvStoreBuffer[j + 2] << 24);
                                    uiGetPacketSize |= (uint)(recvStoreBuffer[j + 3] << 16);
                                    uiGetPacketSize |= (uint)(recvStoreBuffer[j + 4] << 8);
                                    uiGetPacketSize |= (uint)(recvStoreBuffer[j + 5] << 0);

                                    int iGetSize = (int)uiGetPacketSize;

                                    iGetSize += XCommons.PAD_SIZE;

                                    if (recvStoreBuffer[j + iGetSize - 4] == 0x0D &&
                                    recvStoreBuffer[j + iGetSize - 3] == 0x02 &&
                                    recvStoreBuffer[j + iGetSize - 2] == 0x08 &&
                                    recvStoreBuffer[j + iGetSize - 1] == 0x0A)
                                    {
                                        iFindDataCnt = iGetSize;

                                        ucFindData = new byte[iFindDataCnt];
                                        Array.Copy(recvStoreBuffer, j, ucFindData, 0, iFindDataCnt);

                                        bDataFind = true;

                                        break;
                                    }
                                    else
                                    {
                                        bDataFind = false;

                                        break;
                                    }
                                }
                            }
                            //
                            if (bDataFind)
                            {
                                //성공한 패킷이 있을경우 해당 패킷 제거
                                foreach (var m in QPacketAllData.ToList())
                                {
                                    for (int i = 0; i < guidUsePacketID.Count(); i++)
                                    {
                                        if (m.ID == guidUsePacketID[i])
                                        {
                                            QPacketAllData.Dequeue();

                                            break;
                                        }
                                    }
                                }

                                break;
                            }
                        }

                        QPacketRemainData.Clear();

                        //recvText += Encoding.Unicode.GetString(recvBuffer, 0, nReadSize);

                        /*
                        for (int i = 0; i < iStoreCnt; i++)
                        {
                            if (recvStoreBuffer[i] == 0x0D &&
                                recvStoreBuffer[i + 1] == 0x02 &&
                                recvStoreBuffer[i + 6] == 0x08 &&
                                recvStoreBuffer[i + 7] == 0x0A)
                            {
                                ucGetLabel = recvStoreBuffer[i - 1];

                                uint uiGetPacketSize = 0x0;

                                uiGetPacketSize |= (uint)(recvStoreBuffer[i + 2] << 24);
                                uiGetPacketSize |= (uint)(recvStoreBuffer[i + 3] << 16);
                                uiGetPacketSize |= (uint)(recvStoreBuffer[i + 4] << 8);
                                uiGetPacketSize |= (uint)(recvStoreBuffer[i + 5] << 0);

                                int iGetSize = (int)uiGetPacketSize;

                                iGetSize += XCommons.PAD_SIZE;

                                if (recvStoreBuffer[i + iGetSize - 4] == 0x0D &&
                                recvStoreBuffer[i + iGetSize - 3] == 0x02 &&
                                recvStoreBuffer[i + iGetSize - 2] == 0x08 &&
                                recvStoreBuffer[i + iGetSize - 1] == 0x0A)
                                {
                                    iFindDataCnt = iGetSize;

                                    bSegmentFind = true;
                                }
                                if (bSegmentFind)
                                {
                                    iCheckRetryCnt = 0;

                                    ucFindData = new byte[iFindDataCnt];
                                    ucSetClearArray = new byte[(iFindDataCnt + 1)];

                                    Array.Clear(ucSetClearArray, 0, (iFindDataCnt + 1));
                                    Array.Copy(recvStoreBuffer, i, ucFindData, 0, iFindDataCnt);

                                    iStoreCnt -= (iFindDataCnt + 1);

                                    Buffer.BlockCopy(ucSetClearArray, 0, recvStoreBuffer, 0, (iFindDataCnt + 1));
                                    Buffer.BlockCopy(recvStoreBuffer, iStoreCnt, recvStoreBuffer, 0, USER_MAX_SIZE - iStoreCnt);

                                    bDataFind = true;

                                    break;
                                }
                                else
                                {
                                    iCheckRetryCnt++;

                                    if (iCheckRetryCnt > MAX_CHECK_COUNT)
                                    {
                                        iCheckRetryCnt = 0;

                                        ucSetClearArray = new byte[iFindDataCnt];
                                        Array.Clear(ucSetClearArray, 0, iFindDataCnt);

                                        iStoreCnt -= iFindDataCnt;

                                        Buffer.BlockCopy(ucSetClearArray, 0, recvStoreBuffer, 0, iFindDataCnt);
                                        Buffer.BlockCopy(recvStoreBuffer, iStoreCnt, recvStoreBuffer, 0, USER_MAX_SIZE - iStoreCnt);
                                    }

                                    break;
                                }
                            }
                        }
                        */
                    }
                    catch (Exception e)
                    {
                        bDataFind = false;

                        /*
                        iStoreCnt = 0;

                        if (recvStoreBuffer != null) Array.Clear(recvStoreBuffer, 0, recvStoreBuffer.Count());
                        */
                    }
                    //
                    if (bDataFind)
                    {
                        bool bDataControl = true;

                        byte[] ucGetInfp = null;

                        try
                        {
                            ucGetInfp = new byte[iFindDataCnt];

                            Array.Copy(ucFindData, ucGetInfp, iFindDataCnt);
                        }
                        catch (Exception e)
                        {
                            bDataControl = false;
                        }

                        ScheduleEvent se = null;

                        m_bGetRecv = true;

                        //recvText = string.Empty;

                        if (bDataControl)
                        {
                            se = new ScheduleEvent(nSocketNumber, true, "Recv Success", ucGetLabel);
                        }
                        else
                        {
                            se = new ScheduleEvent(nSocketNumber, false, "Recv Fail", ucGetLabel);
                        }


                        Comm_Recv_Event?.BeginInvoke(ucGetInfp, se, null, null);
                    }

                    this.Receive();
                    //objScoket.WorkSocket.BeginReceive(objScoket.recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), objScoket);
                }
                else
                {
                    this.Dispose();

                    ErrorEventProcess(new Exception("Middleware server side connection lost.[SystemX.Net.Comm : AsyncServerSocket.OnReceiveCallBack]"));
                }
            }
            else
            {
                this.Dispose();

                ErrorEventProcess(new Exception("Middleware server side connection lost.[SystemX.Net.Comm : AsyncServerSocket.OnReceiveCallBack]"));
            }
        }
    }
}
