using System;
using System.Collections.Generic;
using System.Text;
using DBFactory;
namespace SocketsTCPIP
{
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    using System.Text;
    using CommonClassLib;
    public static class CClientTCPIP
    {
        static int _initCount = 0;
        public static DBOperator dbo = new DBOperator();
        public static int TcpIPInitCount
        {
            get { return CClientTCPIP._initCount; }
            set 
            {
                if (value == 0)
                {
                    _tcpError = "";
                }
                CClientTCPIP._initCount = value;

            }
        }
        static bool _ifInit = false;

        public static bool IfInit
        {
            get { return CClientTCPIP._ifInit; }
            set { CClientTCPIP._ifInit = value; }
        }
        static string _remoteIP;
        static int _remotePort;
        static Socket clientSocket=null;
        static EndPoint epServer;
        static byte[] _byteData = new byte[6];
        static string _tcpError;

        public static string TcpError
        {
            get { return _tcpError; }
            set { _tcpError = value; }
        }
        public static byte[] ByteData
        {
            get { return _byteData; }
            set { _byteData = value; }
        }

        public static Socket ClientSocket
        {
            get { return CClientTCPIP.clientSocket; }
            set { CClientTCPIP.clientSocket = value; }
        }

        public static bool InitClientTCPIP(string remoteIP, int remotePort)
        {
            if (_initCount > 3)
            {
                _tcpError = "SocketsTCPIP:连接远程主机时，发生三次连接失败错误！请检查远程主机是否正常运行!重新打开命令开关。";
                _ifInit = false;
                return false;
            }
            clientSocket = null;
            //20100127
            IPAddress ipAddress;
            IPEndPoint remoteEP;
            //byte[] sb;

            // Connect to a remote device.
            try
            {
                _remoteIP = remoteIP;
                _remotePort = remotePort;
                // Establish the remote endpoint for the socket.
                ipAddress = IPAddress.Parse(_remoteIP);

                remoteEP = new IPEndPoint(ipAddress, _remotePort);

                //IPAddress iplocal = IPAddress.Parse("192.168.1.4");

                //IPEndPoint EPlocal = new IPEndPoint(iplocal, 1050);

                epServer = (EndPoint)remoteEP;

                // Create a TCP/IP socket.
                if (clientSocket == null)
                {
                    clientSocket = new Socket(AddressFamily.InterNetwork,
                        SocketType.Stream, ProtocolType.Tcp);

                }
                //clientSocket.Bind((EndPoint)EPlocal);
                // Connect to the remote endpoint.
                //clientSocket.BeginConnect(epServer,
                //    new AsyncCallback(ConnectCallback), clientSocket);
                //_ifInit = true;
                clientSocket.Connect(epServer);
                _ifInit = true;
                //sb = new byte[2] { 61, 0 };
                //clientSocket.Send(sb);
                return _ifInit;

            }
            catch (Exception e)
            {
                if (_initCount > 3)
                {
                    _tcpError = "SocketsTCPIP:连接远程主机时，发生三次连接失败错误！请检查远程主机是否正常运行!重新打开命令开关。";
                    clientSocket = null;
                    //_initCount = 0;
                    
                    return false;
                }
                _initCount++;
                _ifInit = false;

                _tcpError = "SocketsTCPIP.CClientTCPIP.InitClientTCPIP:" + e.Message;
                return false;
            }
            finally
            {//20100127
                ipAddress=null ;
                remoteEP=null ;
                //sb = null;
            }
        }

        private static void ConnectCallback(IAsyncResult ar)
        {
            //20100127
            Socket sk;
            byte[] sb;

            try
            {
                // Retrieve the socket from the state object.
                sk = (Socket)ar.AsyncState;

                // Complete the connection.
                sk.EndConnect(ar);
                _ifInit = true;
               sb = new byte[2] { 61, 0 };
                sk.Send(sb);
                

            }
            catch (Exception e)
            {
                _tcpError = "SocketsTCPIP.CClientTCPIP.ConnectCallback:" + e.Message;
                _ifInit = false;
            }
            finally
            {
                sk = null;//20100127
                sb = null;//20100127
            }
        }

        public static byte[] Receive(string remoteIP, int remotePort)
        {
            try
            {
                if (_ifInit == false)
                {
                    if (InitClientTCPIP(remoteIP, remotePort) == false) return null;
                }
                

                // Begin receiving the data from the remote device.
                clientSocket.BeginReceive(_byteData, 0, _byteData.Length, 0,
                    new AsyncCallback(ReceiveCallback), clientSocket);

                return _byteData;
            }
            catch (Exception e)
            {
                _ifInit = false;
                _tcpError = "SocketsTCPIP.CClientTCPIP.Receive:" + e.Message;
                return null;
            }
        }

        private static void ReceiveCallback(IAsyncResult ar)
        {
            //20100127
            Socket client;
            try
            {
                // Retrieve the state object and the client socket 

                client = (Socket)ar.AsyncState;
                //System.Threading.Thread.Sleep(10);
                // Read data from the remote device.
                client.EndReceive(ar);
                //clientSocket.BeginReceive(_byteData, 0, _byteData.Length, 0,
                //    new AsyncCallback(ReceiveCallback), client);

                CCarryConvert.WriteDarkCasket("SocketsTCPIP.CClientTCPIP", "ReceiveCallback", client.RemoteEndPoint.ToString(), _byteData);
            }
            catch (Exception e)
            {
                _ifInit = false;
                _tcpError = "SocketsTCPIP.CClientTCPIP.ReceiveCallback:" + e.Message;
            }
            finally
            {//20100127
                client=null ;
            }
        }

        public static bool  Send(string remoteIP, int remotePort,byte[] data)
        {
            
            try
            {
                if (_ifInit == false)
                {
                    if (InitClientTCPIP(remoteIP, remotePort) == false)
                    {
                        return false;
                    }
                }
                //20100127

                // Begin sending the data to the remote device.
                clientSocket.Send(data);
                //clientSocket.BeginSend(byteData, 0, byteData.Length, 0,
                //    new AsyncCallback(SendCallback), clientSocket);
                CCarryConvert.WriteDarkCasket("SocketsTCPIP.CClientTCPIP", "Send", clientSocket.RemoteEndPoint.ToString(), data);//20100127
                
                return true;
            }
            catch (Exception e)
            {
                _ifInit = false;
                _tcpError = "SocketsTCPIP.CClientTCPIP.Send:" + e.Message;
                return false;
            }
        }

        private static void SendCallback(IAsyncResult ar)
        {
            Socket client;//20100127
            try
            {
                // Retrieve the socket from the state object.
                //20100127
                client = (Socket)ar.AsyncState;

                // Complete sending the data to the remote device.
                client.EndSend(ar);

            }
            catch (Exception e)
            {
                _ifInit = false;
                _tcpError = "SocketsTCPIP.CClientTCPIP.SendCallback:" + e.Message;


            }
            finally
            {//20100127
                client = null;
            }
        }
        public static void EndConnect()
        {
            
            if (_ifInit == false)
            {
                return ;
                
            }
            byte[] sb=new byte[2]{62,0};
            if (clientSocket.Connected == true)
            {
                clientSocket.Send(sb);
            }
            sb = null;//20100127
        }


    }
 

}
