Socket 客户端【连接池形式】
2012-03-26 23:24
183 查看
阻塞模式,每次需要连接时从池中取一个有效连接,有心跳机制(为了保持长连接)
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; } } } }
相关文章推荐
- java socket客户端连接池
- 使用Socket创建带连接池的多线程文件传输服务器和客户端实例
- 深入研究socket编程(3)——使用select函数编写客户端和服务器
- Android Socket服务端与客户端用字符串的方式互相传递图片的方法
- socket编程 ------ 客户端(非阻塞方式)
- Android客户端 和 pc服务器 建立socket连接并发送数据
- 客户端套接字(Socket)超时
- 在Android上实现SSL握手(客户端需要密钥和证书),实现服务器和客户端之间Socket交互
- 基于Qt-socketio客户端与Nodejs服务器通讯
- socket编程中客户端常用函数 以及简单实现
- java socket 进阶话题一: socket 客户端连接管理
- java socket编程,客户端发出检索字段,服务端查询数据并返回结果集
- python使用tcp socket 传输文件-服务端,客户端
- android客户端和java服务端之间用socket来传输图片
- Android之socket客户端
- Linux系统编程(34)—— socket编程之TCP服务器与客户端的交互
- ServerSocket多个客户端连接问题(原创,作者:cnzrs)
- Socket实现客户端和服务端 简单的入门实例
- 服务器和客户端的交互方式(Socket,http协议)和各自特点适用范围
- Socket编程--客户端InputStream数据读取