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; } } } }