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

using Cosmos.BaseFrame;
using Cosmos.UserFrame;
using System.IO;

namespace Cosmos.Common
{
    /// <summary>
    /// Implements TCP Socket based on Socket Class.
    /// <para>(Socket 클래스를 Base로 한 TCP 소켓을 구현합니다.)</para>
    /// </summary>
    public class TcpSocket
    {
        public Socket m_sckClient;
        private IAsyncResult iarResult;
        private Timer m_timSocketWaitOne = null;        //소켓통신 종료 시간
        private bool m_bolStopSocketTimer = false;      //true-일정 시간 후 소켓자동종료(false:접속완료 후 Timer등록, true:일정시간 후 Timer종료)

        private int m_socketTimeOut = 20000;            //데이터 수신 Timeout
        private bool m_socketConnected = false;
        private string m_IpAddr = "";
        private int m_PortNo;

        public int COMM_MSGLEN_START = 0;               //메시지 길이 시작 위치
        public const int COMM_MSGLEN = 6;               //전문헤더에서 전문헤더를 제외한 전문길이를 나타내는 전문자리수 6
        public const int COMM_HEAD_LEN = 59;            //전문헤더 길이 64

        public bool m_bolUnicode = false;

        #region 생성자
        /// <summary>
        /// Registers the generated Socket.
        /// <para>(생성된 소켓을 등록합니다.)</para>
        /// </summary>
        /// <param name="pSckClient">Socket to be registered</param>
        ///                    <para>(등록할 소켓)</para>
        public TcpSocket(Socket pSckClient)
        {
            m_sckClient = pSckClient;
            m_sckClient.ReceiveTimeout = m_socketTimeOut;
        }
        /// <summary>
        /// Registers the generated Socket.
        /// <para>(생성된 소켓을 등록합니다.)</para>
        /// </summary>
        public TcpSocket()
        {
        }
        /// <summary>
        /// Generates Socket.
        /// <para>(소켓을 생성합니다.)</para>
        /// </summary>
        /// <param name="pStrIP">Server IP</param>
        ///                <para>(서버의 IP)</para>
        /// <param name="pIntPort">Server Port</param>
        ///                  <para>(서버의 Port)</para>
        /// <example>It is an example to send/receive Data after generating Socket.
        ///   <para>(소켓 생성후 데이타를 송수신처리하는 예제이다.)</para>
        /// <code>
        /// try 
        /// {
        ///     m_IrtSocket = new TcpSocket(m_ServerIp, m_ServerPort);
        /// 
        ///     nRecvLen = m_IrtSocket.SendReceiveData(pExplicit, ref rRecvData, 15000);
        ///     if (nRecvLen > 0)
        ///     {
        ///         pRecvData = rRecvData;
        ///         nStat = BaseCom.OK;
        ///     }
        ///     else
        ///     {
        ///         pRecvData = "";
        ///     }
        ///     m_IrtSocket.Close();
        /// }
        /// catch (Exception e)
        /// {
        ///     if (m_IrtSocket != null) m_IrtSocket.Close();
        /// }
        /// </code>
        /// </example>
        public TcpSocket(string pStrIP, int pIntPort)
        {
            m_IpAddr = pStrIP;
            m_PortNo = pIntPort;
        }
        /// <summary>
        /// Generates Socket.
        /// <para>(소켓을 생성합니다.)</para>
        /// </summary>
        /// <param name="pStrIP">Server IP</param>
        ///                <para>(서버의 IP)</para>
        /// <param name="pIntPort">Server Port</param>
        ///                  <para>(서버의 Port)</para>
        /// <param name="pIntTime">Recv TimeOut</param>
        public TcpSocket(string pStrIP, int pIntPort, int pIntTime)
        {
            m_IpAddr = pStrIP;
            m_PortNo = pIntPort;
            m_socketTimeOut = pIntTime;
        }
        /// <summary>
        /// Generates Socket.
        /// <para>(소켓을 생성합니다.)</para>
        /// </summary>
        /// <param name="pStrIP">Server IP</param>
        ///                <para>(서버의 IP)</para>
        /// <param name="pIntPort">Server Port</param>
        ///                  <para>(서버의 Port)</para>
        /// <param name="pIntTime">Recv TimeOut</param>
        /// <para>TimeOut</para>
        /// <param name="pBolStop">Whether or not to stop automatically</param>
        ///                  <para>(자동종료여부)</para>
        public TcpSocket(string pStrIP, int pIntPort, int pIntTime, bool pBolStop)
        {
            m_IpAddr = pStrIP;
            m_PortNo = pIntPort;
            m_socketTimeOut = pIntTime;
            m_bolStopSocketTimer = pBolStop;								// true:일정시간후 소켓자동종료
        }
        #endregion

        /// <summary>
        /// Synchronous Socket Connection
        /// <para>(동기식 소켓 접속)</para>
        /// </summary>
        /// <param name="pIntTime">Delay time to close connection(-1:종료안함)</param>
        ///                  <para>(접속TimeOut)</para>
        /// <returns>Connection Result</returns>
        ///    <para>(접속결과)</para>
        public int Connect(int pIntTime)
        {
            IPAddress _IPAddr;

            if (CmUtil.IsNumber(m_IpAddr.Replace(".", "")) == false)
            {
                IPHostEntry hostInfo = Dns.GetHostEntry(m_IpAddr);          // Get DNS host information.
                IPAddress[] IPaddresses = hostInfo.AddressList;             // Get the DNS IP addresses associated with the host.
                
                _IPAddr = IPaddresses[0];
            }
            else
            {
                _IPAddr = IPAddress.Parse(m_IpAddr);
            }
            IPEndPoint _EP = new IPEndPoint(_IPAddr, m_PortNo);

            if (pIntTime > 0)
            {
                //m_timSocketWaitOne = new System.Threading.Timer(new TimerCallback(TimerSocketWaitOne), null, pIntTime, Timeout.Infinite);
            }

            Socket tempSocket =
                new Socket(_EP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            tempSocket.Connect(_EP);

            if (tempSocket.Connected)
            {
                m_sckClient = tempSocket;
                m_sckClient.ReceiveTimeout = m_socketTimeOut;

                return BaseCom.OK;
            }
            else
            {
                //ConsoleNx.WriteLine("Socket Message : Socket Connection failed !!! " + m_IpAddr + " " + m_PortNo.ToString());
            }
            return BaseCom.NG;
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Socket Connection Request [External]
        /// <para>(소켓 연결 요청[External])</para>
        /// </summary>
        /// <param name="pBolStop">Automatic Socket Stop</param>
        ///                  <para>(소켓자동종료)</para>
        /* --------------------------------------------------------------------------------- */
        public int Connect(bool pBolStop)
        {
            m_bolStopSocketTimer = pBolStop;								// 접속후 일정시간후 소켓 자동종료
            InitSocket(m_IpAddr, m_PortNo, m_socketTimeOut);

            if (!m_socketConnected) return BaseCom.NG;

            return BaseCom.OK;
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Socket Connection Request [Internal]
        /// <para>(소켓 연결 요청[Internal])</para>
        /// </summary>
        /// <param name="pIntTime">Timeout Time</param>
        ///                  <para>(Timeout시간)</para>
        /// <param name="pBolStop">Automatic Socket Stop</param>
        ///                  <para>(소켓자동종료)</para>
        /* --------------------------------------------------------------------------------- */
        private int Connect(bool pBolStop, int pIntTime)
        {
            m_bolStopSocketTimer = pBolStop;								// true:일정시간후 소켓 자동종료,false-자동종료안함.
            InitSocket(m_IpAddr, m_PortNo, pIntTime);

            if (!m_socketConnected) return BaseCom.NG;

            return BaseCom.OK;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Synchronous Connection
        /// <para>(동기식 연결)</para>
        /// </summary>
        /// <param name="pStrIP">Connection IP</param>
        ///                <para>(접속 IP)</para>
        /// <param name="pIntPort">Connection Port</param>
        ///                  <para>(접속 Port)</para>
        /// <param name="pIntTime">Connection Timeout</param>
        ///                  <para>(접속 Timeout)</para>
        /* --------------------------------------------------------------------------------- */
        private void InitSocket(string pStrIP, int pIntPort, int pIntTime)
        {
            // Ip에서 왼쪽 0을 삭제하고, 000은 0으로 변환합니다
            //--------------------------------------------------------------------------------------
            pStrIP = BsUtil.TrimNetworkIpAddress(pStrIP);

            // Ip로 연결을 실행합니다.
            //--------------------------------------------------------------------------------------
            //ConsoleNx.WriteLine("TcpSocket Message : TcpSocket Connect Start !!! "+pStrIP+" "+pIntPort.ToString());
            m_timSocketWaitOne = new System.Threading.Timer(new TimerCallback(TimerSocketWaitOne), null, pIntTime, Timeout.Infinite);

            m_sckClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress _IPAddr = IPAddress.Parse(pStrIP);
            IPEndPoint _EP = new IPEndPoint(_IPAddr, pIntPort);

            iarResult = m_sckClient.BeginConnect(_EP, new AsyncCallback(CallBackConnectMethod), m_sckClient);   // 비동기식 연결
            iarResult.AsyncWaitHandle.WaitOne();                                                                // AsyncCallback 완료될때까지 대기      
            //ConsoleNx.WriteLine("TcpSocket Message : TcpSocket Connect End !!! " + pStrIP + " " + pIntPort);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Socket Connection Callback Function
        /// <para>(소켓 연결 Callback 함수)</para>
        /// </summary>
        /// <param name="iar"></param>
        /* --------------------------------------------------------------------------------- */
        private void CallBackConnectMethod(IAsyncResult iar)
        {
            Socket sckConnected = (Socket)iar.AsyncState;
            try
            {
                if (sckConnected.Connected)									// 접속 성공
                {
                    m_socketConnected = true;
                    //------------------------------------------------------------------------------
                    // 연결 접속이 되면 EndConnect를 호출하고, 이벤트 대리자를 실행합니다.
                    //------------------------------------------------------------------------------
                    sckConnected.EndConnect(iar);
                    if (!m_bolStopSocketTimer)								// 일정시간후 소켓 자동종료
                    {
                        m_timSocketWaitOne.Dispose();
                        m_timSocketWaitOne = null;
                    }
                }
                else
                {
                    m_socketConnected = false;
                    //------------------------------------------------------------------------------
                    // 접속된 소켓을 종료합니다.
                    //------------------------------------------------------------------------------
                    sckConnected.Close();
                }
            }
            catch (Exception) { }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// 송신 처리 프로세스. Byte, String 모두 Send는 Byte로 변환해서 송신
        /// </summary>
        /// <param name="pSocket">소켓객체</param>
        /// <param name="pSendData">송신데이타</param>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        private int SendProc(Socket pSocket, string pSendData)
        {
            try
            {
                Byte[] sBytTempBuff;

                sBytTempBuff = Encoding.UTF8.GetBytes(pSendData);     // sStrSize + pSendData --> sStrSize
                
                int nByte = pSocket.Send(sBytTempBuff, sBytTempBuff.Length, SocketFlags.None);
            }
            catch (Exception ex)
            {
                return BaseCom.NG;
            }
            return BaseCom.OK;
        }

        private int KDSSendProc(Socket pSocket, string pSendData)
        {
            try
            {
                Byte[] sBytTempBuff;

                sBytTempBuff = Encoding.GetEncoding("euc-kr").GetBytes(pSendData);

                int nByte = pSocket.Send(sBytTempBuff, sBytTempBuff.Length, SocketFlags.None);
            }
            catch (Exception ex)
            {
                return BaseCom.NG;
            }
            return BaseCom.OK;
        }

        private int SendProcEx(Socket pSocket, string pSendData)
        {
            try
            {
                Byte[] sBytTempBuff;

                sBytTempBuff = Encoding.Default.GetBytes(pSendData);     // sStrSize + pSendData --> sStrSize

                int nByte = pSocket.Send(sBytTempBuff, sBytTempBuff.Length, SocketFlags.None);
            }
            catch (Exception ex)
            {
                return BaseCom.NG;
            }
            return BaseCom.OK;
        }
        #region ###### 데이타 송수신 String 처리 ######
                
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Data Send/Receive Processing
        /// <para>(데이타 송/수신 처리)</para>
        /// </summary>
        /// <param name="pSendData">Send Data</param>
        ///                   <para>(송신데이타)</para>
        /// <param name="rRecvData">Receive Data</param>
        ///                   <para>(수신데이타)</para>
        /// <param name="pIntTime">Timeout</param>
        ///                  <para>(타임아웃)</para>
        /// <returns></returns>
        /// <example>It is an example to send/receive Data after generating Socket.
        /// <para>(소켓 생성후 데이타를 송수신처리하는 예제이다.)</para>
        /// <code>
        /// try 
        /// {
        ///     m_IrtSocket = new TcpSocket(m_ServerIp, m_ServerPort);
        /// 
        ///     nRecvLen = m_IrtSocket.SendReceiveData(pExplicit, ref rRecvData, 15000);
        ///     if (nRecvLen > 0)
        ///     {
        ///         pRecvData = rRecvData;
        ///         nStat = BaseCom.OK;
        ///     }
        ///     else
        ///     {
        ///         pRecvData = "";
        ///     }
        ///     m_IrtSocket.Close();
        /// }
        /// catch (Exception e)
        /// {
        ///     if (m_IrtSocket != null) m_IrtSocket.Close();
        /// }
        /// </code>
        /// </example>
        /* --------------------------------------------------------------------------------- */
        public int SendReceiveData(string pSendData, ref string rRecvData, int pIntTime)
        {
            return SendReceiveData(pSendData, ref rRecvData, pIntTime, true, 0, "", -1, false);
        }
        public int SendReceiveData(string pSendData, ref string rRecvData, int pIntTime, bool bIsDmbIf)
        {
            return SendReceiveData(pSendData, ref rRecvData, pIntTime, true, 0, "", -1, false, bIsDmbIf);
        }
        public int SendReceiveData(string pSendData, ref string rRecvData, int pIntTime, int nRecvDataLen, string sAckData)
        {
            return SendReceiveData(pSendData, ref rRecvData, pIntTime, true, nRecvDataLen, sAckData, -1, false);
        }
        public int SendReceiveData(string pSendData, ref string rRecvData, int pIntTime, int nRecvDataLen, string sAckData, bool bErrorSkip)
        {
            return SendReceiveData(pSendData, ref rRecvData, pIntTime, true, nRecvDataLen, sAckData, -1, bErrorSkip);
        }
        public int SendReceiveData(string pSendData, ref string rRecvData, int pIntTime, bool bFullSize, int nRecvDataLen, string sAckData, int nRecvDataStartPosion, bool bErrorSkip, bool bIsDmbIf = false)
        {
            int nStat = BaseCom.OK;
            int rDataLen = 0;
            string rTempData = "";

            try
            {
                nStat = Connect(pIntTime);                     // 동기식 Socket 접속

                if (nStat != BaseCom.OK)         // 접속실패
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.SendReceiveData()", "Connection Failed !!!");
                    return BaseCom.NG;
                }

                // Send request to the server.
                if (nRecvDataLen == 0)
                    nStat = SendProc(m_sckClient, pSendData);
                else
                    nStat = SendProcEx(m_sckClient, pSendData);
                
                if (nStat != BaseCom.OK)         // 송신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.SendReceiveData()", "Send Data Failed !!!");
                    return BaseCom.NG1;
                }

                // Receive the server home page content.
                if (bErrorSkip == true)
                    nStat = RecvProcEx_ErrSkip(ref rTempData, ref rDataLen, nRecvDataLen);
                else if (nRecvDataLen == 0)
                {
                    if (bIsDmbIf == false)
                    {
                        nStat = RecvProc(ref rTempData, ref rDataLen);
                    }
                    else
                    {
                        //#16569 파스쿠찌 드라이브 스루 기능 개발 요청 start
                        //기존
                        //nStat = RecvProc(ref rTempData, ref rDataLen, 324);
                        //변경
                        nStat = RecvProcEx(ref rTempData, ref rDataLen, 324);
                        //#16569 파스쿠찌 드라이브 스루 기능 개발 요청 end
                    }
                }
                else if (nRecvDataStartPosion == -1)
                    nStat = RecvProcEx(ref rTempData, ref rDataLen, nRecvDataLen);
                else
                    nStat = RecvProcLen(ref rTempData, ref rDataLen, bFullSize, nRecvDataLen, nRecvDataStartPosion);

                if (nStat != BaseCom.OK)         // 수신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.SendReceiveData()", "Receive Data Failed !!!");
                    return BaseCom.NG2;
                }

                if (sAckData != "")
                {
                    // Send request to the server.
                    nStat = SendProc(m_sckClient, sAckData);
                    if (nStat != BaseCom.OK)         // 송신실패
                    {
                        Close();
                        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                            "TcpSocket.SendReceiveData()", "Send  AckData Failed !!!");
                        return BaseCom.NG1;
                    }
                }
                Close();
                rRecvData = rTempData;
            }
            catch (Exception e)
            {
                Close();

                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.SendReceiveData()", e.ToString());
            }

            return rDataLen;
        }
        /// <summary>
        /// Data Send/Receive Processing
        /// </summary>
        /// <param name="pSendData">Data to send</param>
        /// <param name="rRecvData">Data to receive</param>
        /// <param name="pIntTime">time to keep the connection</param>
        /// <param name="pRecvDataLen">Data length size</param>
        /// <param name="pRecvDataStartPosition">Start position for header length of receiving data</param>
        /// <returns></returns>
        public int SendReceiveData(string pSendData, ref string rRecvData, int pIntTime, int pRecvDataLen, int pRecvDataStartPosition)
        {
            int nStat = BaseCom.OK;
            int rDataLen = 0;
            string rTempData = "";

            try
            {
                nStat = Connect(pIntTime);      // 동기식 Socket 접속

                if(nStat != BaseCom.OK)         // 접속실패
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                         System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                         System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                         System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                         "Connection Failed !!!");
                    return BaseCom.NG;
                }

                // Send request to the server.
                nStat = SendProc(m_sckClient, pSendData);

                if(nStat != BaseCom.OK)         // 송신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                         System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                         System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                         System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                         "Send Data Failed !!!");
                    return BaseCom.NG1;
                }

                // Receive the server home page content
                nStat = RecvProcLen(ref rTempData, ref rDataLen, true, pRecvDataLen, pRecvDataStartPosition);

                if(nStat != BaseCom.OK)         // 수신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                         System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                         System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                         System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                         "Receive Data Failed !!!");
                    return BaseCom.NG2;
                }

                Close();
                rRecvData = rTempData;
            }
            catch(Exception e)
            {
                Close();

                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                     e.Message);
            }

            return rDataLen;
        }

        public int KDSSendReceiveData(string pSendData, ref string rRecvData, int pIntTime, int pRecvDataLen, int pRecvDataStartPosition)
        {
            int nStat = BaseCom.OK;
            int rDataLen = 0;
            string rTempData = "";

            try
            {
                nStat = Connect(pIntTime);      // 동기식 Socket 접속

                if (nStat != BaseCom.OK)         // 접속실패
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                         System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                         System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                         System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                         "Connection Failed !!!");
                    return BaseCom.NG;
                }

                // Send request to the server.
                nStat = KDSSendProc(m_sckClient, pSendData);

                if (nStat != BaseCom.OK)         // 송신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                         System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                         System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                         System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                         "Send Data Failed !!!");
                    return BaseCom.NG1;
                }

                // Receive the server home page content
                nStat = RecvProcLen(ref rTempData, ref rDataLen, true, pRecvDataLen, pRecvDataStartPosition);

                if (nStat != BaseCom.OK)         // 수신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                         System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                         System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                         System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                         "Receive Data Failed !!!");
                    return BaseCom.NG2;
                }

                Close();
                rRecvData = rTempData;
            }
            catch (Exception e)
            {
                Close();

                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                     e.Message);
            }

            return rDataLen;
        }
        
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Receive Processing Process
        /// <para>(수신 처리 프로세스)</para>
        /// </summary>
        /// <param name="pRecvData">수신데이타</param>
        /// <param name="pRecvLen">수신데이타 길이</param>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        private int RecvProc(ref string pRecvData, ref int pRecvLen, int pHeaderLen = COMM_HEAD_LEN)
        {
            int intRecvSize = 0;
            Byte[] bytHeadBuff = new Byte[pHeaderLen]; // COMM_MSGLEN --> COMM_HEAD_LEN  //  (pbolUnicode) ? COMM_MSGLEN*2 : 
            //Byte[] bytHeadBuff = new Byte[200]; // COMM_MSGLEN --> COMM_HEAD_LEN  //  (pbolUnicode) ? COMM_MSGLEN*2 :
            string strHeadBuff = "";

           // 공통해더 수신
            try
            {
                intRecvSize = m_sckClient.Receive(bytHeadBuff, bytHeadBuff.Length, SocketFlags.None);
                //strHeadBuff = Encoding.Default.GetString(bytHeadBuff, 0, intRecvSize);
                strHeadBuff = Encoding.UTF8.GetString(bytHeadBuff, 0, intRecvSize);
            }
            catch (Exception e)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.RecvProc()", "Comm Header Receive Failed, " + e.Message);
                return BaseCom.NG1;
            }

            int nDataSize = 0;
            // 데이터 길이 체크
            try
            {
                nDataSize = Int32.Parse(CmUtil.MidH(strHeadBuff, COMM_MSGLEN_START, COMM_MSGLEN));
            }
            catch (Exception)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.RecvProc()", "Comm Header Analysis Error, strCommHead[" + strHeadBuff + "]");
                return BaseCom.NG3;
            }

            string strDataBuff = "";
            // 데이터 수신
            if (nDataSize > 0)
            {
                // 데이타를 수신하기 위하여 정의합니다.
                //--------------------------------------------------------------------------------------
                int intDataIndex = 0;
                int intSizeRemain = nDataSize;
                Byte[] bytDataBuff = new Byte[nDataSize];
                Byte[] bytTempBuff = new Byte[nDataSize];
                //Byte[] bytDataBuff = new Byte[200];
                //Byte[] bytTempBuff = new Byte[200];

                try
                {
                    // 소켓으로부터 데이타를 수신합니다 (읽을 데이터가 없으면 메서드가 차단됩니다).
                    //--------------------------------------------------------------------------------------
                    do
                    {
                        intRecvSize = m_sckClient.Receive(bytTempBuff, intSizeRemain, SocketFlags.None);
                        intSizeRemain -= intRecvSize;

                        // 수신한 데이타를 보관하고, 초기화 합니다.
                        //----------------------------------------------------------------------------------
                        for (int i = 0; i < intRecvSize; i++)
                        {
                            bytDataBuff[intDataIndex++] = bytTempBuff[i];
                        }
                        bytTempBuff.Initialize();
                    }
                    while (intSizeRemain > 0);  // intSizeRemain != 0
                }
                catch (Exception e)
                {
                    //Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.RecvProc()", "Receive Data Analysis Error, " + e.Message);
                    return BaseCom.NG3;
                }
                // 수신한 데이타를 Ascii로 바꿉니다.
                //strDataBuff = Encoding.Default.GetString(bytDataBuff, 0, nDataSize);  // intTotalSize --> intSizeRemain
                strDataBuff = Encoding.UTF8.GetString(bytDataBuff, 0, nDataSize);  // intTotalSize --> intSizeRemain
            }
            // 수신한 데이타를 Message로 Parsing 합니다.

            pRecvData = strHeadBuff + strDataBuff;           // strDataAscii    --> strCommHead + strDataAscii
            pRecvLen = nDataSize;                        // intRecvSize     --> intTotalSize

            // Debugger를 위하여 출력합니다.
            //--------------------------------------------------------------------------------------
            return BaseCom.OK;

        }
        private int RecvProcEx(ref string pRecvData, ref int pRecvLen, int nDataSize)
        {
            int intRecvSize = 0;
            string strDataBuff = "";

            // 데이터 수신
            if (nDataSize > 0)
            {
                // 데이타를 수신하기 위하여 정의합니다.
                //--------------------------------------------------------------------------------------
                int intDataIndex = 0;
                int intSizeRemain = nDataSize;
                Byte[] bytDataBuff = new Byte[nDataSize];
                Byte[] bytTempBuff = new Byte[nDataSize];

                try
                {
                    // 소켓으로부터 데이타를 수신합니다 (읽을 데이터가 없으면 메서드가 차단됩니다).
                    //--------------------------------------------------------------------------------------
                    do
                    {
                        intRecvSize = m_sckClient.Receive(bytTempBuff, intSizeRemain, SocketFlags.None);

                        if (intRecvSize <= 0)
                        {
                            UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name, "TcpSocket.RecvProcEx()", "Data Receive Failed, ");
                            return BaseCom.NG3;
                        }

                        intSizeRemain -= intRecvSize;

                        // 수신한 데이타를 보관하고, 초기화 합니다.
                        //----------------------------------------------------------------------------------
                        for (int i = 0; i < intRecvSize; i++)
                        {
                            bytDataBuff[intDataIndex++] = bytTempBuff[i];
                        }
                        bytTempBuff.Initialize();
                    }
                    while (intSizeRemain > 0);  // intSizeRemain != 0
                }
                catch (Exception e)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.RecvProcEx()", "Receive Data Analysis Error, " + e.Message);
                    return BaseCom.NG3;
                }
                // 수신한 데이타를 Ascii로 바꿉니다.
                strDataBuff = Encoding.Default.GetString(bytDataBuff, 0, nDataSize);  // intTotalSize --> intSizeRemain
                //strDataBuff = Encoding.UTF8.GetString(bytDataBuff, 0, nDataSize);  // intTotalSize --> intSizeRemain
            }
            // 수신한 데이타를 Message로 Parsing 합니다.

            pRecvData = strDataBuff;           
            pRecvLen = nDataSize;                        // intRecvSize     --> intTotalSize

            return BaseCom.OK;
        }

        private int RecvProcEx_ErrSkip(ref string pRecvData, ref int pRecvLen, int nDataSize)
        {
            int intRecvSize = 0;
            string strDataBuff = "";

            // 데이터 수신
            if (nDataSize > 0)
            {
                // 데이타를 수신하기 위하여 정의합니다.
                //--------------------------------------------------------------------------------------
                int intDataIndex = 0;
                int intSizeRemain = nDataSize;
                Byte[] bytDataBuff = new Byte[nDataSize];
                Byte[] bytTempBuff = new Byte[nDataSize];

                try
                {
                    // 소켓으로부터 데이타를 수신합니다 (읽을 데이터가 없으면 메서드가 차단됩니다).
                    //--------------------------------------------------------------------------------------
                    do
                    {
                        intRecvSize = m_sckClient.Receive(bytTempBuff, intSizeRemain, SocketFlags.None);
                        if (intRecvSize <= 0)
                        {
                            UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name, "TcpSocket.RecvProcEx_ErrSkip()", "Data Receive Failed, ");
                            return BaseCom.NG3;
                        }

                        intSizeRemain -= intRecvSize;

                        // 수신한 데이타를 보관하고, 초기화 합니다.
                        //----------------------------------------------------------------------------------
                        for (int i = 0; i < intRecvSize; i++)
                        {
                            bytDataBuff[intDataIndex++] = bytTempBuff[i];
                        }
                        bytTempBuff.Initialize();

                        m_sckClient.ReceiveTimeout = 600;
                    }
                    while (intSizeRemain > 0);  // intSizeRemain != 0
                }
                catch (Exception e)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.RecvProcEx_ErrSkip()", "Receive Data Analysis Error, " + e.Message);
                    //return BaseCom.NG3;
                }
                // 수신한 데이타를 Ascii로 바꿉니다.
                strDataBuff = Encoding.Default.GetString(bytDataBuff, 0, nDataSize);  // intTotalSize --> intSizeRemain
                strDataBuff = Encoding.UTF8.GetString(bytDataBuff, 0, nDataSize);  // intTotalSize --> intSizeRemain
            }
            // 수신한 데이타를 Message로 Parsing 합니다.

            pRecvData = strDataBuff;
            pRecvLen = nDataSize;                        // intRecvSize     --> intTotalSize

            return BaseCom.OK;
        }
        
        private int RecvProcLen(ref string pRecvData, ref int pRecvLen, bool bFullSize, int nRecvDataLen, int nRecvDataStartPosion)
        {
            int intRecvSize = 0;
            Byte[] bytHeadBuff = new Byte[nRecvDataStartPosion + nRecvDataLen];     //해더: 
            string strHeadBuff = "";

            // 해더 수신
            try
            {
                intRecvSize = m_sckClient.Receive(bytHeadBuff, bytHeadBuff.Length, SocketFlags.None);
                strHeadBuff = Encoding.Default.GetString(bytHeadBuff, 0, intRecvSize);
            }
            catch (Exception e)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.RecvProcLen()", "Comm Header Receive Failed, " + e.Message);
                return BaseCom.NG1;
            }

            int nDataSize = 0;
            // 데이터 길이 체크
            try
            {
                nDataSize = Int32.Parse(CmUtil.MidH(strHeadBuff, nRecvDataStartPosion, nRecvDataLen));

                // 길이가 = 전체인 경우 (Body 길이만큼이면 -하지 않는다)
                if (bFullSize != true)
                    nDataSize -= nRecvDataStartPosion + nRecvDataLen;
            }
            catch (Exception)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.RecvProcLen()", "Comm Header Analysis Error, strCommHead[" + strHeadBuff + "]");
                return BaseCom.NG3;
            }

            string strDataBuff = "";
            // 데이터 수신
            if (nDataSize > 0)
            {
                // 데이타를 수신하기 위하여 정의합니다.
                //--------------------------------------------------------------------------------------
                int intDataIndex = 0;
                int intSizeRemain = nDataSize;
                Byte[] bytDataBuff = new Byte[nDataSize];
                Byte[] bytTempBuff = new Byte[nDataSize];

                try
                {
                    // 소켓으로부터 데이타를 수신합니다 (읽을 데이터가 없으면 메서드가 차단됩니다).
                    //--------------------------------------------------------------------------------------
                    do
                    {
                        intRecvSize = m_sckClient.Receive(bytTempBuff, intSizeRemain, SocketFlags.None);
                        intSizeRemain -= intRecvSize;

                        // 수신한 데이타를 보관하고, 초기화 합니다.
                        //----------------------------------------------------------------------------------
                        for (int i = 0; i < intRecvSize; i++)
                        {
                            bytDataBuff[intDataIndex++] = bytTempBuff[i];
                        }
                        bytTempBuff.Initialize();
                    }
                    while (intSizeRemain > 0);  // intSizeRemain != 0
                }
                catch (Exception e)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.RecvProcLen()", "Receive Data Analysis Error, " + e.Message);
                    return BaseCom.NG3;
                }
                // 수신한 데이타를 Ascii로 바꿉니다.
                strDataBuff = Encoding.Default.GetString(bytDataBuff, 0, nDataSize);  // intTotalSize --> intSizeRemain
            }
            // 수신한 데이타를 Message로 Parsing 합니다.

            pRecvData = strHeadBuff + strDataBuff;
            pRecvLen = nRecvDataStartPosion + nRecvDataLen + nDataSize;                     

            // Debugger를 위하여 출력합니다.
            //--------------------------------------------------------------------------------------
            return BaseCom.OK;

        }
        #endregion

        #region ###### 데이타 송수신 Byte 처리 ######

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Data Send/Receive Processing
        /// <para>(데이타 송/수신 처리)</para>
        /// </summary>
        /// <param name="pSenddata">Send Data</param>
        ///                   <para>(송신데이타)</para>
        /// <param name="pRecvdata">Receive Data</param>
        ///                   <para>(수신데이타)</para>
        /// <param name="pIntTime">Timeout</param>
        ///                  <para>(타임아웃)</para>
        /// <returns></returns>
        /// <example>It is an example to send/receive Data after generating Socket.
        /// <para>(소켓 생성후 데이타를 송수신처리하는 예제이다.)</para>
        /// <code>
        /// try 
        /// {
        ///     m_IrtSocket = new TcpSocket(m_ServerIp, m_ServerPort);
        /// 
        ///     nRecvLen = m_IrtSocket.SendReceiveData(pExplicit, ref rRecvData, 15000);
        ///     if (nRecvLen > 0)
        ///     {
        ///         pRecvData = rRecvData;
        ///         nStat = BaseCom.OK;
        ///     }
        ///     else
        ///     {
        ///         pRecvData = "";
        ///     }
        ///     m_IrtSocket.Close();
        /// }
        /// catch (Exception e)
        /// {
        ///     if (m_IrtSocket != null) m_IrtSocket.Close();
        /// }
        /// </code>
        /// </example>
        /* --------------------------------------------------------------------------------- */
        public int SendReceiveData(byte[] pSenddata, ref byte[] pRecvdata, int pIntTime)
        {
            return SendReceiveData(pSenddata, ref pRecvdata, pIntTime, 0, null, -1);
        }
        public int SendReceiveData(byte[] pSenddata, ref byte[] pRecvdata, int pIntTime, int nRecvDataLen, byte[] pAckData)
        {
            return SendReceiveData(pSenddata, ref pRecvdata, pIntTime, 0, pAckData, -1);
        }
        public int SendReceiveData(byte[] pSenddata, ref byte[] pRecvdata, int pIntTime, int nRecvDataLen, byte[] pAckData, int nRecvDataStartPosion)
        {
            int nStat = BaseCom.OK;
            int rDataLen = 0;

            //ConsoleNx.WriteLine("TcpSocket Message : SendReceiveData Start !!!");

            //if (m_sckClient == null) return BaseCom.NG3;

            // Create a socket connection with the specified server and port.
            //nStat = Connect(true, pIntTime);      // 접속요청후 10초뒤 소켓종료, 접속완료시는 Timeout 설정 유효
            try
            {
                nStat = Connect(pIntTime);                     // 동기식 Socket 접속

                if (nStat != BaseCom.OK)         // 접속실패
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.SendReceiveData()", "Connection Failed !!!");
                    return BaseCom.NG;
                }

                // Send request to the server.
                try
                {
                    int nByte = m_sckClient.Send(pSenddata, pSenddata.Length, SocketFlags.None);

                    // Send request to the server.
                    //nStat = SendProc(m_sckClient, pSenddata);
                }
                catch (Exception ex)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        "TcpSocket.SendReceiveData()", "Send Data Failed [" + ex.Message + "]");
                    nStat = BaseCom.NG;
                }

                if (nStat != BaseCom.OK)         // 송신실패
                {
                    Close();

                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.SendReceiveData()", "Send Data Failed !!!");

                    return BaseCom.NG;
                }

                if (nRecvDataLen == 0)
                    pRecvdata = RecvProc(ref rDataLen);
                else if (nRecvDataStartPosion == -1)
                    pRecvdata = RecvProcEx(ref rDataLen, nRecvDataLen);
                else
                    pRecvdata = RecvProcLen(ref rDataLen, nRecvDataLen, nRecvDataStartPosion);

                if (nStat != BaseCom.OK)         // 수신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.SendReceiveData()", "Receive Data Failed !!!");

                    return BaseCom.NG;
                }

                if (pAckData != null)
                {
                    try
                    {
                        int nByte = m_sckClient.Send(pAckData, pAckData.Length, SocketFlags.None);
                    }
                    catch (Exception ex)
                    {
                        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                            "TcpSocket.SendReceiveData()", "Send AckData Failed [" + ex.Message + "]");
                        nStat = BaseCom.NG;
                    }
                }
                Close();
            }
            catch (Exception e)
            {
                Close();
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.SendReceiveData()", e.ToString());

            }

            return rDataLen;
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// 수신 처리 프로세스
        /// </summary>
        /// <param name="pRecvLen">수신데이타 길이</param>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        public virtual Byte[] RecvProc(ref int pRecvLen)
        {
            byte[] byteRecvData = null;

            int intRecvSize = 0;
            Byte[] bytHeadBuff = new Byte[COMM_HEAD_LEN]; // COMM_MSGLEN --> COMM_HEAD_LEN  //  (pbolUnicode) ? COMM_MSGLEN*2 : 
            string strHeadBuff = "";
            byte[] bytRecvDataBuff = null;

            // 공통해더 수신
            try
            {
                intRecvSize = m_sckClient.Receive(bytHeadBuff, bytHeadBuff.Length, SocketFlags.None);

                strHeadBuff = Encoding.Default.GetString(bytHeadBuff, 0, intRecvSize);
            }
            catch (Exception e)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.RecvProc()", e.ToString());
                return byteRecvData;
            }

            int nDataSize = 0;
            // 데이터 길이 체크
            try
            {
                nDataSize = Int32.Parse(CmUtil.MidH(strHeadBuff, COMM_MSGLEN_START, COMM_MSGLEN));
            }
            catch (Exception)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.RecvProc()", "Comm Header Analysis Error!! strCommHead[" + strHeadBuff + "]");
                return byteRecvData;
            }

            // 데이터 수신
            if (nDataSize >= COMM_HEAD_LEN)
            {
                // 데이타를 수신하기 위하여 정의합니다.
                //--------------------------------------------------------------------------------------
                int intDataIndex = 0;
                int intSizeRemain = nDataSize - COMM_HEAD_LEN;
                Byte[] bytDataBuff = new Byte[nDataSize];
                Byte[] bytTempBuff = new Byte[nDataSize];

                try
                {
                    // 소켓으로부터 데이타를 수신합니다 (읽을 데이터가 없으면 메서드가 차단됩니다).
                    //--------------------------------------------------------------------------------------
                    do
                    {
                        intRecvSize = m_sckClient.Receive(bytTempBuff, intSizeRemain, SocketFlags.None);
                        intSizeRemain -= intRecvSize;

                        // 수신한 데이타를 보관하고, 초기화 합니다.
                        //----------------------------------------------------------------------------------
                        for (int i = 0; i < intRecvSize; i++)
                        {
                            bytDataBuff[intDataIndex++] = bytTempBuff[i];
                        }
                        bytTempBuff.Initialize();
                    }
                    while (intSizeRemain > 0);  // intSizeRemain != 0
                }
                catch (Exception e)
                {
                    //Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.RecvProc()", "Receive Data Analysis Error!!" + e.ToString());
                    return byteRecvData;
                }

                bytRecvDataBuff = new byte[nDataSize - COMM_HEAD_LEN];
                Array.Copy(bytDataBuff, 0, bytRecvDataBuff, 0, nDataSize - COMM_HEAD_LEN);

            }
            // 수신한 데이타를 Message로 Parsing 합니다.
            byteRecvData = new byte[nDataSize];

            Array.Copy(bytHeadBuff, 0, byteRecvData, 0, bytHeadBuff.Length);
            Array.Copy(bytRecvDataBuff, 0, byteRecvData, bytHeadBuff.Length, bytRecvDataBuff.Length);

            pRecvLen = nDataSize;                                   // intRecvSize     --> intTotalSize

            return byteRecvData;

        }
        public virtual Byte[] RecvProcEx(ref int pRecvLen, int nRecvDataSize)
        {
            
            // 데이타를 수신하기 위하여 정의합니다.
            //--------------------------------------------------------------------------------------
            int intSizeRemain = nRecvDataSize;

            int intRecvSize = 0;
            Byte[] bytTempBuff = new Byte[nRecvDataSize];
            int intDataIndex = 0;
            Byte[] bytDataBuff = new Byte[nRecvDataSize];
                
            try
            {
                // 소켓으로부터 데이타를 수신합니다 (읽을 데이터가 없으면 메서드가 차단됩니다).
                //--------------------------------------------------------------------------------------
                do
                {
                    intRecvSize = m_sckClient.Receive(bytTempBuff, intSizeRemain, SocketFlags.None);
                    if (intRecvSize <= 0)
                    {
                        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name, "TcpSocket.RecvProcEx()", "Data Receive Failed, ");
                        return bytDataBuff;
                    }

                    intSizeRemain -= intRecvSize;

                    // 수신한 데이타를 보관하고, 초기화 합니다.
                    //----------------------------------------------------------------------------------
                    for (int i = 0; i < intRecvSize; i++)
                    {
                        bytDataBuff[intDataIndex++] = bytTempBuff[i];
                    }
                    bytTempBuff.Initialize();
                }
                while (intSizeRemain > 0);  // intSizeRemain != 0
            }
            catch (Exception e)
            {
                //Close();
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.RecvProcEx()", "Receive Data Analysis Error!!" + e.ToString());
                return bytDataBuff;
            }
            return bytDataBuff;

        }
        public virtual Byte[] RecvProcLen(ref int pRecvLen, int nRecvDataLen, int nRecvDataStartPosion)
        {
            byte[] byteRecvData = null;

            int intRecvSize = 0;
            Byte[] bytHeadBuff = new Byte[nRecvDataStartPosion + nRecvDataLen]; // 해더 
            string strHeadBuff = "";
            byte[] bytRecvDataBuff = null;

            // 해더 수신
            try
            {
                intRecvSize = m_sckClient.Receive(bytHeadBuff, bytHeadBuff.Length, SocketFlags.None);

                strHeadBuff = Encoding.Default.GetString(bytHeadBuff, 0, intRecvSize);
            }
            catch (Exception e)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.RecvProcLen()", e.ToString());
                return byteRecvData;
            }

            int nDataSize = 0;
            // 데이터 길이 체크
            try
            {
                nDataSize = Int32.Parse(CmUtil.MidH(strHeadBuff, nRecvDataStartPosion, nRecvDataLen));
                nDataSize -= nRecvDataStartPosion + nRecvDataLen;
            }
            catch (Exception)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.RecvProcLen()", "Comm Header Analysis Error!! strCommHead[" + strHeadBuff + "]");
                return byteRecvData;
            }

            // 데이터 수신
            if (nDataSize >= 0)
            {
                // 데이타를 수신하기 위하여 정의합니다.
                //--------------------------------------------------------------------------------------
                int intDataIndex = 0;
                int intSizeRemain = nDataSize;
                Byte[] bytDataBuff = new Byte[nDataSize];
                Byte[] bytTempBuff = new Byte[nDataSize];

                try
                {
                    // 소켓으로부터 데이타를 수신합니다 (읽을 데이터가 없으면 메서드가 차단됩니다).
                    //--------------------------------------------------------------------------------------
                    do
                    {
                        intRecvSize = m_sckClient.Receive(bytTempBuff, intSizeRemain, SocketFlags.None);
                        intSizeRemain -= intRecvSize;

                        // 수신한 데이타를 보관하고, 초기화 합니다.
                        //----------------------------------------------------------------------------------
                        for (int i = 0; i < intRecvSize; i++)
                        {
                            bytDataBuff[intDataIndex++] = bytTempBuff[i];
                        }
                        bytTempBuff.Initialize();
                    }
                    while (intSizeRemain > 0);  // intSizeRemain != 0
                }
                catch (Exception e)
                {
                    //Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.RecvProc()", "Receive Data Analysis Error!!" + e.ToString());
                    return byteRecvData;
                }

                bytRecvDataBuff = new byte[nDataSize];
                Array.Copy(bytDataBuff, 0, bytRecvDataBuff, 0, nDataSize);

            }
            // 수신한 데이타를 Message로 Parsing 합니다.
            byteRecvData = new byte[nDataSize];

            Array.Copy(bytHeadBuff, 0, byteRecvData, 0, bytHeadBuff.Length);
            Array.Copy(bytRecvDataBuff, 0, byteRecvData, bytHeadBuff.Length, bytRecvDataBuff.Length);

            pRecvLen = nRecvDataStartPosion + nRecvDataLen + nDataSize;  

            return byteRecvData;

        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Receive Processing Process
        /// <para>(수신 처리 프로세스)</para>
        /// </summary>
        /// <param name="pRecvLen">Receive Data
        ///                  <para>(수신데이타)</para></param>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        public virtual Byte[] FoodRecvProc(ref int pRecvLen)
        {
            int intRecvSize = 0;

            Byte[] bytSizeBuff = new Byte[1];

            try
            {
                if (m_sckClient != null)
                {
                    intRecvSize = m_sckClient.Receive(bytSizeBuff, bytSizeBuff.Length, SocketFlags.None);

                    string sRecv = Encoding.Default.GetString(bytSizeBuff, 0, bytSizeBuff.Length);

                    //UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                    //                    "TcpSocket.FoodRecvProc()", "Return Code=" + sRecv);

                    if (intRecvSize > 0)
                    {
                        pRecvLen = intRecvSize;
                        return bytSizeBuff;
                    }
                }
            }
            catch (SocketException se)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.FoodRecvProc()", "SocketErrorCode =" + se.SocketErrorCode.ToString() + ", ErrorCode=" + se.ErrorCode.ToString());
                return null;
            }
            catch (Exception e)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.FoodRecvProc()", e.Message);
                return null;
            }

            return bytSizeBuff;
        }

        #endregion

        #region ###### 마스터 데이타 송수신 String 처리 ######
        /// <summary>
        /// 마스터 요청 송수신 처리
        /// </summary>
        /// <param name="pSendData"></param>
        /// <param name="pRecvData"></param>
        /// <returns></returns>
        public int SendReceiveMstData(string pSendData, ref string pRecvData)
        {
            int iReadLen = 0;
            int iReturn = BaseCom.NG;
            DateTime dtStart;
            DateTime dtEnd;
            TimeSpan span;
            try
            {
                dtStart = DateTime.Now;
                iReturn = SendProc(m_sckClient, pSendData);
                if (iReturn != BaseCom.OK)      // 송신실패
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.SendReceiveMstData()", "Send Data Failed !!!");
                    return BaseCom.NG2;
                }

                iReturn = RecvProc(ref pRecvData, ref iReadLen);
                if (iReturn != BaseCom.OK)      // 수신실패
                {
                    dtEnd = DateTime.Now;
                    span = dtEnd.Subtract(dtStart);
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "(" + span.Minutes + ":" + span.Seconds + ")TcpSocket.SendReceiveMstData()", "Receive Data Failed !!!" + " : " + pSendData);
                    return BaseCom.NG2;
                }
            }
            catch (Exception e)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    "TcpSocket.SendReceiveMstData()", e.ToString());
            }

            return iReadLen;
        }
        /// <summary>
        /// 마스터 요청에 대한 응답 후 수신 처리
        /// </summary>
        /// <param name="pRecvData"></param>
        /// <returns></returns>
        public int ReceiveMstData(ref string pRecvData)
        {
            int iReturn = BaseCom.NG;
            int iReadLen = 0;
            try
            {
                iReturn = RecvProc(ref pRecvData, ref iReadLen);
                if (iReturn != BaseCom.OK)      // 수신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                        "TcpSocket.SendReceiveMstData()", "Receive Data Failed !!!");
                    return BaseCom.NG2;
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                     ex.Message);
            }

            return iReadLen;
        }
        #endregion

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Data Receive Processing
        /// <para>(데이타 수신 처리)</para>
        /// </summary>
        /// <param name="pRecvData">Receive Data</param>
        ///                   <para>(수신 데이타)</para>
        /// <returns>Receive Data Length</returns>
        ///    <para>(수신데이타길이)</para>
        /* --------------------------------------------------------------------------------- */
        public int RecvData(ref string pRecvData)
        {
            int nStat = BaseCom.OK;
            int sDataLen = 0;
            string sTempData = "";

            try
            {
                if (m_sckClient == null) return 0;

                nStat = RecvProc(ref sTempData, ref sDataLen);

                if (nStat != BaseCom.OK)
                {
                    return BaseCom.NG;
                }

                pRecvData = sTempData;
            }
            catch (Exception)
            {
                return BaseCom.NG1;
            }
            return BaseCom.OK;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Data Receive Processing
        /// <para>(데이타 수신 처리)</para>
        /// </summary>
        /// <param name="pRecvData">수신 데이타</param>
        /// <param name="pRecvTimeout">수신 타임아웃</param>
        /// <returns>수신데이타길이</returns>
        /* --------------------------------------------------------------------------------- */
        public int RecvData(ref string pRecvData, int pRecvTimeout)
        {
            m_timSocketWaitOne = new System.Threading.Timer(new TimerCallback(TimerSocketWaitOne), null, pRecvTimeout, Timeout.Infinite);
            return RecvData(ref pRecvData);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Data Send Processing
        /// <para>(데이타 송신 처리)</para>
        /// </summary>
        /// <param name="pSendData">Send Data</param>
        ///                   <para>(송신 데이타)</para>
        /// <returns>Send Data Length</returns>
        ///    <para>(송신데이타길이)</para>
        /* --------------------------------------------------------------------------------- */
        public int SendData(string pSendData)
        {
            int nStat = BaseCom.OK;

            try
            {
                if (m_sckClient == null) return 0;

                // Send request to the server.
                nStat = SendProc(m_sckClient, pSendData);

                if (nStat != BaseCom.OK)
                {
                    return BaseCom.NG;
                }
            }
            catch (Exception)
            {
                return BaseCom.NG1;
            }
            return BaseCom.OK;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Stops Socket in connection.
        /// <para>(연결중인 소켓을 종료합니다.)</para>
        /// </summary>
        /* --------------------------------------------------------------------------------- */
        public void Close()
        {
            try
            {
                if (m_sckClient.Connected)
                {
                    m_sckClient.Blocking = false;
                    m_sckClient.Shutdown(SocketShutdown.Both);
                    m_sckClient.Close();
                }
            }
            catch (Exception) { }

            // 소켓이 종료될 경우 타이머를 종료합니다.
            //--------------------------------------------------------------------------------------
            if (m_timSocketWaitOne != null)
            {
                m_timSocketWaitOne.Dispose();
                m_timSocketWaitOne = null;
            }
            m_sckClient = null;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Stops Socket after Socket connection, non-connection and a certain time.
        /// <para>(소켓연결, 비연결후 일정시간후 소켓을 종료합니다.)</para>
        /// </summary>
        /// <param name="sender"></param>
        /* --------------------------------------------------------------------------------- */
        private void TimerSocketWaitOne(object sender)
        {
            try
            {
                ((ManualResetEvent)iarResult.AsyncWaitHandle).Set();
                m_timSocketWaitOne.Dispose();
                m_timSocketWaitOne = null;
                //Close();
            }
            catch (Exception)
            {

            }
            finally
            {
                Close();
            }
        }

        /// <summary>
        /// Gets Client Socket.
        /// <para>(Client Socket를 구합니다. )</para>
        /// </summary>
        public Socket ClientSocket
        {
            get
            {
                return m_sckClient;
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Gets connected Remote IP.
        /// <para>(접속된 Remote의 IP를 구합니다.)</para>
        /// </summary>
        /* --------------------------------------------------------------------------------- */
        public string RemoteIp
        {
            get
            {
                try
                {
                    return ((IPEndPoint)m_sckClient.RemoteEndPoint).Address.ToString();
                }
                catch (Exception)
                {
                    return null;
                }
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get connected Remote Port No.
        /// <para>(접속된 Remote Port의 번호 구합니다.)</para>
        /// </summary>
        /* --------------------------------------------------------------------------------- */
        public string RemotePort
        {
            get
            {
                try
                {
                    string pIntPort = ((IPEndPoint)this.m_sckClient.RemoteEndPoint).Port.ToString();
                    return pIntPort;
                }
                catch (Exception)
                {
                    return null;
                }

            }
        }

        /// <summary>
        /// GET / SET set-up IP of Server
        /// <para>(서버의 설정된 IP 값을 GET / SET )</para>
        /// </summary>
        public string IP
        {
            get
            {
                return m_IpAddr;
            }
            set
            {
                m_IpAddr = value;
            }
        }

        /// <summary>
        /// GET / SET Port value of Server
        /// <para>(서버의 설정된 PORT 값을 GET / SET )</para>
        /// </summary>
        public int PORT
        {
            get
            {
                return m_PortNo;
            }
            set
            {
                m_PortNo = value;
            }
        }

        /// <summary>
        /// 푸드 프린터로 상태 체크 Data Send/Receive Processing
        /// </summary>
        /// <param name="pSenddata">Send Data</param>
        ///                   <para>(송신데이타)</para>
        /// <param name="pRecvdata">Receive Data</param>
        ///                   <para>(수신데이타)</para>
        /// <param name="pIntTime">Timeout</param>
        ///                  <para>(타임아웃)</para>
        /// <returns></returns>
        public int SendReceiveFoodPrintData(byte[] pSenddata, ref byte[] pRecvdata, int pIntTime)
        {
            //int nStat = BaseCom.NG;
            int rDataLen = 0;
            int nByte = 0;
            try
            {
                //nStat = Connect(pIntTime);                     // 동기식 Socket 접속

                //if (nStat != BaseCom.OK)         // 접속실패
                //{
                //    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                //                        "TcpSocket.SendReceiveFoodPrintData()", "Connection Failed !!!");
                //    return BaseCom.NG;
                //}

                // Send request to the server.
                try
                {
                    if (this.m_sckClient != null)
                        nByte = this.m_sckClient.Send(pSenddata, pSenddata.Length, SocketFlags.None);
                }
                catch (Exception ex)
                {
                    //nStat = BaseCom.NG;
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                        "TcpSocket.SendReceiveFoodPrintData()", "Exception=" + ex.Message);
                }

                if (nByte != pSenddata.Length)         // 송신실패
                {
                    Close();

                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                        "TcpSocket.SendReceiveFoodPrintData()", "Send Data Failed !!!");

                    return BaseCom.NG;
                }

                Byte[] bytRecvData = FoodRecvProc(ref rDataLen);

                //if (nStat != BaseCom.OK)         // 수신실패
                if (rDataLen != 1)         // 수신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                        "TcpSocket.SendReceiveFoodPrintData()", "Receive Data Failed !!!");

                    return BaseCom.NG;
                }

                //Close();

                pRecvdata = bytRecvData;
            }
            catch (Exception e)
            {
                Close();
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.SendReceiveFoodPrintData()", e.Message);
                return BaseCom.NG;
            }

            return BaseCom.OK; // rDataLen;
        }

        /// <summary>
        /// 푸드 프린터로 Send. 응답기다리지 않음
        /// </summary>
        /// <param name="pSenddata"></param>
        /// <param name="pIntTime"></param>
        /// <returns></returns>
        public int SendFoodPrintData(byte[] pSenddata)
        {
            int nStat = BaseCom.NG;
            int nByte = 0;
            try
            {
                //nStat = Connect(pIntTime);       // 동기식 Socket 접속

                //if (nStat != BaseCom.OK)         // 접속실패
                //{
                //    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                //                        "TcpSocket.SendFoodPrintData()", "Connection Failed !!!");
                //    return BaseCom.NG;
                //}

                // Send request to the server.
                try
                {
                    if (this.m_sckClient != null)
                        nByte = this.m_sckClient.Send(pSenddata, pSenddata.Length, SocketFlags.None);
                }
                catch (Exception ex)
                {
                    nStat = BaseCom.NG;
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                        "TcpSocket.SendFoodPrintData()", "Exception=" + ex.Message);
                }

                if (nByte != pSenddata.Length)         // 송신실패
                {
                    Close();

                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                        "TcpSocket.SendFoodPrintData()", "Send Data Failed !!!");
                    return BaseCom.NG;
                }

                //Close();

            }
            catch (Exception e)
            {
                Close();
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.SendFoodPrintData()", e.Message);
                return BaseCom.NG;
            }

            return BaseCom.OK; // rDataLen;
        }

        /// <summary>
        /// Socket Send & Receive
        /// </summary>
        /// <param name="pSendData">Send Data</param>
        /// <param name="nRecvLenLength">Receive Data Length of Length</param>
        /// <param name="rRecvData">Receive Data</param>
        /// <param name="pIntTime">Time Out</param>
        /// <returns>return</returns>
        public int ByPassSendReceiveData(byte[] pSendData, int nRecvLenLength, ref byte[] rRecvData, int pIntTime)
        {
            int nStat = BaseCom.OK;

            rRecvData = new byte[nRecvLenLength];
            try
            {
                nStat = Connect(pIntTime);                     // 동기식 Socket 접속

                if (nStat != BaseCom.OK)         // 접속실패
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                        "TcpSocket.ByPassSendReceiveData()", "Connection Failed !!!");
                    return BaseCom.NG;
                }

                // Data Send
                nStat = ByPassSendProc(m_sckClient, pSendData);

                if (nStat != BaseCom.OK)         // 송신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                        "TcpSocket.ByPassSendReceiveData()", "Send Data Failed !!!");
                    return BaseCom.NG1;
                }

                // Data Receive
                nStat = ByPassRecvProc(ref rRecvData, ref nRecvLenLength);

                if (nStat != BaseCom.OK)         // 수신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                        "TcpSocket.ByPassSendReceiveData()", "Receive Data Failed -> 0!!!");
                    return BaseCom.NG2;
                }

                Close();
            }
            catch (Exception ex)
            {
                Close();
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.ByPassSendReceiveData()", ex.Message);
            }

            return nRecvLenLength;
        }



        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Send Processing Process
        /// <para>(송신 처리 프로세스)</para>
        /// </summary>
        /// <param name="pSocket">Socket Object</param>
        ///                 <para>(소켓객체)</para>
        /// <param name="pSendData">Send Data</param>
        ///                   <para>(송신데이타)</para>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        private int ByPassSendProc(Socket pSocket, byte[] pSendData)
        {
            bool pBolUnicode = m_bolUnicode;

            try
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.ByPassSendProc()", "Send Data (" + pSendData.Length + ")[" + pSendData + "]");

                int nByte = pSocket.Send(pSendData, pSendData.Length, SocketFlags.None);
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.ByPassSendProc()", ex.Message);
                return BaseCom.NG;
            }
            return BaseCom.OK;
        }


        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Receive Processing Process
        /// <para>(수신 처리 프로세스)</para>
        /// </summary>
        /// <param name="pRecvData">Socket Object
        ///                   <para>(소켓객체)</para></param>
        /// <param name="pRecvLen">Receive Data
        ///                  <para>(수신데이타)</para></param>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        private int ByPassRecvProc(ref byte[] pRecvData, ref int pRecvLen)
        {
            pRecvData = new Byte[pRecvLen];

            try
            {
                //pRecvLen = m_sckClient.Receive(pRecvData, pRecvData.Length, SocketFlags.None);
                pRecvLen = m_sckClient.Receive(pRecvData, SocketFlags.None);

                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                        "TcpSocket.ByPassRecvProc()", "Recv Data (" + pRecvData.Length + ")]" + pRecvData + "]");
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.ByPassRecvProc()", ex.Message);
                return BaseCom.NG1;
            }

            return BaseCom.OK;
        }

        //20180611 프린터 미출력 개선 02Printer.exe start

        /// <summary>
        /// Prt Socket Send, Receive
        /// </summary>
        /// <param name="pSendData"></param>
        /// <param name="nRecvLenLength"></param>
        /// <param name="rRecvData"></param>
        /// <param name="pIntTime"></param>
        /// <returns></returns>
        public int Prt_ByPassSendReceiveData(byte[] pSendData, int nRecvLenLength, ref byte[] rRecvData, int pIntTime)
        {
            int nStat = BaseCom.OK;

            rRecvData = new byte[nRecvLenLength];
            try
            {
                nStat = Connect(pIntTime);                     // 동기식 Socket 접속

                if (nStat != BaseCom.OK)         // 접속실패
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                        "TcpSocket.ByPassSendReceiveData()", "Connection Failed !!!");
                    return BaseCom.NG;
                }

                // Data Send
                nStat = Prt_ByPassSendProc(m_sckClient, pSendData);

                if (nStat != BaseCom.OK)         // 송신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                        "TcpSocket.ByPassSendReceiveData()", "Send Data Failed !!!");
                    return BaseCom.NG1;
                }

                // Data Receive
                nStat = Prt_ByPassRecvProc(ref rRecvData, ref nRecvLenLength);

                if (nStat != BaseCom.OK)         // 수신실패
                {
                    Close();
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                        "TcpSocket.ByPassSendReceiveData()", "Receive Data Failed -> 0!!!");
                    return BaseCom.NG2;
                }

                Close();
            }
            catch (Exception ex)
            {
                Close();
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.ByPassSendReceiveData()", ex.Message);
            }

            return nRecvLenLength;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Send Processing Process
        /// <para>(송신 처리 프로세스)</para>
        /// </summary>
        /// <param name="pSocket">Socket Object</param>
        ///                 <para>(소켓객체)</para>
        /// <param name="pSendData">Send Data</param>
        ///                   <para>(송신데이타)</para>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        private int Prt_ByPassSendProc(Socket pSocket, byte[] pSendData)
        {
            bool pBolUnicode = m_bolUnicode;

            try
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.ByPassSendProc()", "Send Data (" + pSendData.Length + ")[" + pSendData + "]");

                int nByte = pSocket.Send(pSendData, pSendData.Length, SocketFlags.None);
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.ByPassSendProc()", ex.Message);
                return BaseCom.NG;
            }
            return BaseCom.OK;
        }


        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Receive Processing Process
        /// <para>(수신 처리 프로세스)</para>
        /// </summary>
        /// <param name="pRecvData">Socket Object
        ///                   <para>(소켓객체)</para></param>
        /// <param name="pRecvLen">Receive Data
        ///                  <para>(수신데이타)</para></param>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        private int Prt_ByPassRecvProc(ref byte[] pRecvData, ref int pRecvLen)
        {
            pRecvData = new Byte[pRecvLen];

            try
            {
                //pRecvLen = m_sckClient.Receive(pRecvData, pRecvData.Length, SocketFlags.None);
                pRecvLen = m_sckClient.Receive(pRecvData, SocketFlags.None);
                //pRecvLen = m_sckClient.Receive(pRecvData);

                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                        "TcpSocket.ByPassRecvProc()", "Recv Data (" + pRecvData.Length + ")]" + pRecvData + "]");
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "TcpSocket.ByPassRecvProc()", ex.Message);
                return BaseCom.NG1;
            }

            return BaseCom.OK;
        }

        //20180611 프린터 미출력 개선 02Printer.exe end
    }

    /// <summary>
    /// TCP 클라이언트 동기화 소켓(공통처리 불가한 소켓 송수신 사용)
    /// </summary>
    public class TcpSocketClient
    {
        public Socket m_sckClient;

        /// <summary>
        /// 서버 IP
        /// </summary>
        private string m_IpAddr = "";
        /// <summary>
        /// 서버 PORT
        /// </summary>
        private int m_PortNo;

        public TcpSocketClient()
        {
        }

        /// <summary>
        /// 소켓 접속 처리
        /// </summary>
        /// <param name="sIpAddr"></param>
        /// <param name="nPortNo"></param>
        /// <returns></returns>
        public int Connect(string sIpAddr, int nPortNo)
        {
            m_IpAddr = sIpAddr;
            m_PortNo = nPortNo;

            try
            {
                IPAddress _IPAddr;
                if (CmUtil.IsNumber(m_IpAddr.Replace(".", "")) == false)
                {
                    IPHostEntry hostInfo = Dns.GetHostEntry(m_IpAddr);          // Get DNS host information.
                    IPAddress[] IPaddresses = hostInfo.AddressList;             // Get the DNS IP addresses associated with the host.

                    _IPAddr = IPaddresses[0];
                }
                else
                {
                    _IPAddr = IPAddress.Parse(m_IpAddr);
                }
                IPEndPoint _EP = new IPEndPoint(_IPAddr, m_PortNo);

                Socket tempSocket = new Socket(_EP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                tempSocket.Connect(_EP);
                if (tempSocket.Connected == false)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                        string.Format("Connect Fail  = {0} : {1}", sIpAddr, nPortNo));
                    return BaseCom.NG;
                }

                m_sckClient = tempSocket;

                return BaseCom.OK;
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
                return BaseCom.NG1;
            }
        }

        /// <summary>
        /// 소켓 종료 처리
        /// </summary>
        public void Close()
        {
            try
            {
                if (m_sckClient.Connected == true)
                {
                    m_sckClient.Blocking = false;
                    m_sckClient.Shutdown(SocketShutdown.Both);
                    m_sckClient.Close();
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }

            m_sckClient = null;
        }

        /// <summary>
        /// 데이터 송신 처리
        /// </summary>
        /// <param name="byteSenddata"></param>
        /// <returns></returns>
        public int SendData(byte[] byteSenddata)
        {
            int nByte = 0;

            try
            {
                if (this.m_sckClient != null)
                {
                    nByte = this.m_sckClient.Send(byteSenddata, byteSenddata.Length, SocketFlags.None);
                }

                if (nByte != byteSenddata.Length)         // 송신실패
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", "SendData Fail");
                    return BaseCom.NG;
                }

                UserLog.WriteLogFile(UserCom.LOG_SOCK, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                    CmUtil.RPadH("[SEND" + ":" + m_IpAddr + ":" + m_PortNo, 27) + "] " + Encoding.Default.GetString(byteSenddata));
                return BaseCom.OK;
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
                return BaseCom.NG1;
            }
        }

        /// <summary>
        /// 지정길이 데이터 수신 처리
        /// </summary>
        /// <param name="byteRecvData"></param>
        /// <param name="nRecvDataLen"></param>
        /// <param name="nTimeOut"></param>
        /// <returns></returns>
        public int RecvProc(ref byte[] byteRecvData, int nRecvDataLen, int nTimeOut)
        {
            int intRecvSize = 0;

            try
            {
                if (this.m_sckClient != null)
                {
                    m_sckClient.ReceiveTimeout = nTimeOut;

                    intRecvSize = m_sckClient.Receive(byteRecvData, nRecvDataLen, SocketFlags.None);
                }

                if (intRecvSize > 0)
                {
                    UserLog.WriteLogFile(UserCom.LOG_SOCK, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                        CmUtil.RPadH("[RECV" + ":" + m_IpAddr + ":" + m_PortNo, 27) + "] " + Encoding.Default.GetString(byteRecvData, 0, intRecvSize));
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);

            }
            return intRecvSize;
        }


        /// <summary>
        /// 데이터 수신 처리( ETX 나올때 까지 수신)
        /// </summary>
        /// <param name="byteRecvData"></param>
        /// <param name="nTimeOut"></param>
        /// <returns></returns>
        public int RecvProcEndToETX(ref byte[] byteRecvData, int nTimeOut)
        {
            int intRecvSize = 0;

            try
            {
                if (this.m_sckClient != null)
                {
                    m_sckClient.ReceiveTimeout = nTimeOut;

                    while (true)
                    {
                        byte[] byteRecvTemp = new byte[1];
                        int nSize = m_sckClient.Receive(byteRecvTemp, 1, SocketFlags.None);
                        if (nSize <= 0)
                        {
                            if (intRecvSize > 0)
                            {
                                UserLog.WriteLogFile(UserCom.LOG_SOCK, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                                    CmUtil.RPadH("[RECV FAIL" + ":" + m_IpAddr + ":" + m_PortNo, 27) + "] " + Encoding.Default.GetString(byteRecvData, 0, intRecvSize));
                            }
                            return 0;
                        }
                        byteRecvData[intRecvSize] = byteRecvTemp[0];
                        intRecvSize++;

                        // ETX 수신시 까지 계속 수신
                        if (byteRecvTemp[0] == 0x03) break;
                    }
                }

                if (intRecvSize > 0)
                {
                    UserLog.WriteLogFile(UserCom.LOG_SOCK, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                        CmUtil.RPadH("[RECV" + ":" + m_IpAddr + ":" + m_PortNo, 27) + "] " + Encoding.Default.GetString(byteRecvData, 0, intRecvSize));
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);

            }
            return intRecvSize;
        }
    }
}
