using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using CommonClassLib;
namespace SocketsUDP
{
    public static class CClientUDP
    {

        static Socket clientSocket=null;
        static bool IfInit = false;
        static byte[] _byteData = new byte[16];
        static string _udpError;
        static EndPoint _remoteServer;
        static EndPoint _localServer;
        public static EndPoint RemoteServer
        {
            get { return _remoteServer; }
            set { _remoteServer = value; }
        }
        public static EndPoint LocalServer
        {
            get { return _localServer; }
            set { _localServer = value; }
        }
        public static string UdpError
        {
            get { return _udpError; }
            set { _udpError = value; }
        }
        public static byte[] ByteData
        {
            get { return _byteData; }
            set { _byteData = value; }
        }
        public  static void InitClientUDP(EndPoint localServer, EndPoint remoteServer)
        {
            try
            {
                _localServer = localServer;
                _remoteServer = remoteServer;
                //Using UDP sockets
                if (clientSocket == null)
                {
                    clientSocket = new Socket(AddressFamily.InterNetwork,
                        SocketType.Dgram, ProtocolType.Udp);
                    clientSocket.Bind(_localServer);//Login to the server
                    clientSocket.Connect(_remoteServer);
                }
                clientSocket.SendBufferSize = 1024;
                clientSocket.ReceiveBufferSize = 1024;
                
                IfInit = true;
            }
            catch (Exception ex)
            {
                clientSocket = null;
                IfInit = false;
                _udpError = ex.Message;
                
            }

        }
        public static bool SendUdp(byte[] byteData)
        {
            try
            {
                if (IfInit == false)
                {
                    InitClientUDP(_localServer, _remoteServer);
                }
                clientSocket.Send(byteData, 0, byteData.Length, SocketFlags.None);
                CCarryConvert.WriteDarkCasket(" CClientUDP", "Send", _remoteServer.ToString(), byteData);
                return true;
            }
            catch (Exception ex)
            {
                IfInit = false;
                UdpError = ex.Message;
                return false;
            }
        }
        public static bool SendUdp(string strData)
        {
            try
            {
                if (IfInit == false)
                {
                    InitClientUDP(_localServer, _remoteServer);
                }
                byte[] byteData = Encoding.UTF8.GetBytes(strData);
                clientSocket.Send(byteData, 0, byteData.Length, SocketFlags.None);
                //CCarryConvert.WriteDarkCasket(" CClientUDP", "Send", _remoteServer.ToString(), byteData);
                return true;
            }
            
            catch (Exception ex)
            {
                IfInit = false;
                UdpError = ex.Message;
                return false;
            }
        }
        public static byte[] ReceiveUdp(string localip, int localport)
        {
            try
            {
                if (IfInit == false)
                {
                    InitClientUDP(_localServer, _remoteServer);
                }
                EndPoint epSender;
                if (_remoteServer == null)
                {
                    IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);//接收任何远端主机的任何端口
                    //The epSender identifies the incoming clients
                    epSender = (EndPoint)ipeSender;
                }
                else
                {
                    epSender = _remoteServer;
                }
               

                //Start receiving data
                clientSocket.BeginReceiveFrom(_byteData, 0, _byteData.Length,
                    SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);
                //CCarryConvert.WriteDarkCasket(" CClientUDP", "BeginReceiveFrom", epSender.ToString(), _byteData);
                
                return _byteData;
            }
            catch (Exception ex)
            {
                IfInit = false;
                _udpError = ex.Message;
                return null;
            }
        }
        public static byte[] ReceiveUdp()
        {
            try
            {
                if (IfInit == false)
                {
                    InitClientUDP(_localServer, _remoteServer);
                }
                EndPoint epSender;
                if (_remoteServer == null)
                {
                    IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);//接收任何远端主机的任何端口
                    //The epSender identifies the incoming clients
                    epSender = (EndPoint)ipeSender;
                }
                else
                {
                    epSender = _remoteServer;
                }


                //Start receiving data
                clientSocket.BeginReceiveFrom(_byteData, 0, _byteData.Length,
                    SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);
                //CCarryConvert.WriteDarkCasket(" CClientUDP", "BeginReceiveFrom", epSender.ToString(), _byteData);

                return _byteData;
            }
            catch (Exception ex)
            {
                IfInit = false;
                _udpError = ex.Message;
                return null;
            }
        }
        private static void OnReceive(IAsyncResult ar)
        {
            try
            {
                
                EndPoint epSender;
                if (_remoteServer == null)
                {
                    IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);//接收任何远端主机的任何端口
                    //The epSender identifies the incoming clients
                    epSender = (EndPoint)ipeSender;
                }
                else
                {
                    epSender = _remoteServer;
                }
                clientSocket.EndReceiveFrom(ar, ref epSender);
                
                clientSocket.BeginReceiveFrom(_byteData, 0, _byteData.Length,
                    SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);
            }
            catch (Exception ex)
            {
                IfInit = false;
                _udpError=ex.Message ;
            }
        }
        public static void CloseUDP()
        {
            //if (clientSocket == null) return;
            //if (clientSocket.Connected == true)
            //{
            //    clientSocket.Shutdown(SocketShutdown.Both);
            //}
            //clientSocket.Close();
            //if (clientSocket == null) return;
            //if (clientSocket.Connected == true)
            //{
            //    clientSocket.Shutdown(SocketShutdown.Both);
            //}
            //clientSocket.Close();
            //IfInit = false;
        }
        
    }
}
