Socket 客户端【连接池形式】

阻塞模式,每次需要连接时从池中取一个有效连接,有心跳机制(为了保持长连接)

namespace Client
{
    internal class SocketClient
    {
        private Socket _socketClient;

        /// <summary>
        /// 锁标识(正在发送)
        /// </summary>
        private object Sending = new object();
        /// <summary>
        /// 建立socket连接
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public SocketClient(string ip, int port)
        {
            IPAddress IP = IPAddress.Parse(ip);
            _socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _socketClient.ReceiveTimeout = 25000;
            _socketClient.SendTimeout = 3000;
            this.IsFree = true;
            this.IsDead = false;
            try
            {
                _socketClient.Connect(new IPEndPoint(IP, port)); //配置服务器IP与端口  
            }
            catch
            {
                this.IsFree = false;
                this.IsDead = true;
                //throw new Exception("连接服务器异常");
            }
        }
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] SendData(byte[] data)
        {
            lock (this.Sending)
            {
                this.IsFree = false;
                Byte[] result = null;
                try
                {
                    _socketClient.Send(data, data.Length, 0);
                    Byte[] bytesReceived = new Byte[256];
                    int bytes = 0;
                    do
                    {
                        Console.WriteLine("{0} Receive {1}", DateTime.Now.TimeOfDay.ToString(), _socketClient.LocalEndPoint.ToString());
                        bytes = _socketClient.Receive(bytesReceived, bytesReceived.Length, 0);
                        if (result == null)
                            result = new byte[bytes];
                        else
                        {
                            byte[] newResult = new byte[bytes + result.Length];
                            result.CopyTo(newResult, 0);
                            result = newResult;
                        }
                        if (bytes < 256)
                        {
                            Array.Copy(bytesReceived, 0, result, result.Length - bytes, bytes);
                            break;
                        }
                        else
                            bytesReceived.CopyTo(result, result.Length - bytes);
                    }
                    while (bytes > 0);
                    Console.WriteLine("  Success.");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("{0} Fail {1}",DateTime.Now.TimeOfDay.ToString(),_socketClient.LocalEndPoint.ToString());
                    this.IsDead = true;
                    return null;
                }
                this.IsFree = true;
                return result;
            }
        }

        /// <summary>
        /// 是否空闲
        /// </summary>
        public bool IsFree = true;
        /// <summary>
        /// 是否异常
        /// </summary>
        public bool IsDead = false;
        /// <summary>
        /// 关闭套接字(这个没写好)
        /// </summary>
        public void Close()
        {
            if (_socketClient.Connected)
            {
                _socketClient.Shutdown(SocketShutdown.Both);
                _socketClient.Close();
            }
            else
            {
                try
                {
                    _socketClient.Shutdown(SocketShutdown.Both);
                    _socketClient.Close();
                }
                catch
                {
                    return;
                }
            }
        }

    }

    /// <summary>
    /// Socket池
    /// </summary>
    internal static class SocketPool
    {
        private static object GetLock = new object();

        private static string _Ip;

        private static int _Port;

        private static SocketClient[] _socketPool;// = new SocketClient[3];

        private static System.Timers.Timer _HeartbeatTimer;

        private static readonly byte[] _HeartbeatData = new byte[] { 71, 69, 84, 32, 47, 32, 72, 84, 84, 80, 47, 49, 46, 49, 13, 10, 13, 10 };

        public static bool EnableHeartbeat { get; set; }

        /// <summary>
        /// 初始化Socket池
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="poolLength"></param>
        public static void Initial(string ip, int port, int poolLength)
        {
            _socketPool = new SocketClient[poolLength];
            for (int i = 0; i < poolLength; i++)
            {
                _socketPool[i] = new SocketClient(ip, port);
            }
            _Ip = ip;
            _Port = port;

            if (EnableHeartbeat)
            {
                _HeartbeatTimer = new System.Timers.Timer();
                _HeartbeatTimer.Interval = 20000;
                _HeartbeatTimer.Elapsed += new System.Timers.ElapsedEventHandler(_Heartbeat);
                _HeartbeatTimer.Start();
            }
        }

        /// <summary>
        /// 发送心跳包
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void _Heartbeat(object sender, System.Timers.ElapsedEventArgs e)
        {
            for (int i = 0; i < _socketPool.Length; i++)
            {
                if (_socketPool[i].IsDead)
                {
                    //socket异常
                    _socketPool[i].Close();
                    _socketPool[i] = new SocketClient(_Ip, _Port);
                }
                if (_socketPool[i] != null && _socketPool[i].IsFree && !_socketPool[i].IsDead)
                {
                    Console.WriteLine("{0} Send Pack",DateTime.Now);
                    //发送心跳
                    _socketPool[i].SendData(_HeartbeatData);
                    
                }
            }
            Console.WriteLine("---");
        }
        /// <summary>
        /// 获取空闲的Socket连接
        /// </summary>
        /// <returns></returns>
        private static SocketClient _GetFreeConnection()
        {
            lock (GetLock)
            {
                for (int i = 0; i < _socketPool.Length; i++)
                {
                    if (_socketPool[i].IsDead)
                    {
                        //socket异常
                        _socketPool[i].Close();
                        _socketPool[i] = new SocketClient(_Ip, _Port);
                    }
                    if (_socketPool[i].IsFree)
                    {
                        //如果找到一个空闲的
                        _socketPool[i].IsFree = false;
                        return _socketPool[i];
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 获取套接字
        /// </summary>
        /// <returns></returns>
        public static SocketClient GetSocket()
        {
            SocketClient result = null;
            result = _GetFreeConnection();
            if (result != null) return result;
            else
            {
                Stopwatch t = new Stopwatch();
                t.Start();
                while (result == null)
                {
                    result = _GetFreeConnection();
                    if (t.ElapsedMilliseconds > 25000) break;
                }
                t.Stop();
                return result;
            }
        }
    }
}

  

 

posted @ 2012-03-26 23:24  ailove  阅读(7011)  评论(1编辑  收藏  举报
返回顶端^