解決問題: 1. Socket 的異常斷開 服務器
2. 部署在IIS程序池上的程序回收致使 端口占用,對象資源卻已經釋放的BUG框架
SocketHelper 類 inOptionValues .net框架中用於檢測鏈接的客戶端 檢測時間(默認2小時) 或者本身寫個心跳包(客戶端和服務端用規定協議) socket
1 #region 變量 2 3 //服務器監聽socket 4 public static Socket listener = null; 5 6 /// <summary> 7 /// 鏈接列表 8 /// </summary> 9 public static List<Socket> socketList = new List<Socket>(); 10 11 public static Thread listenClientThread = null; 12 13 private static byte[] inOptionValues = null; 14 15 #endregion 16 17 18 19 #region 開啓監聽 (接收數據) 20 21 /// <summary> 22 /// 開啓監聽 23 /// </summary> 24 public static void StartListening() 25 { 26 uint dummy = 0; 27 inOptionValues = new byte[Marshal.SizeOf(dummy) * 3]; 28 BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0); //是否啓用Keep-Alive 29 BitConverter.GetBytes((uint)30000).CopyTo(inOptionValues, Marshal.SizeOf(dummy)); //檢測客戶端時間週期 30 BitConverter.GetBytes((uint)2000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2); //失敗後連續探測時間 31 32 byte[] bytes = new Byte[1024]; 33 //首先是構造一個socket對象 34 IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); 35 IPAddress ip = null; 36 foreach (var item in ipHostInfo.AddressList) 37 { 38 if (item.AddressFamily == AddressFamily.InterNetwork) 39 { 40 ip = item; 41 break; 42 } 43 } 44 IPAddress ipAddress = ipHostInfo.AddressList[0]; 45 //System.Web.HttpContext.Current.A 46 IPEndPoint localEndPoint = new IPEndPoint(ip, int.Parse(System.Configuration.ConfigurationManager.AppSettings["Port"])); 47 listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 48 try 49 { 50 listener.Bind(localEndPoint); 51 listener.Listen(100);//開始監聽 52 53 while (true) 54 { 55 // 接收請求鏈接,handler接收該鏈接,以後使用handler處理收發數據的問題 56 Socket handler = listener.Accept(); 57 handler.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null); 58 59 IPEndPoint clientipe = (IPEndPoint)handler.RemoteEndPoint; 60 //SetServerLog("*******" + handler.RemoteEndPoint + "已鏈接服務器,正在監聽!********"); 61 //SetConnectList(handler.RemoteEndPoint.ToString(), true); 62 63 Thread nowThread = new Thread(new ParameterizedThreadStart(ReceiveClientData)); 64 nowThread.IsBackground = true; 65 nowThread.Name = handler.RemoteEndPoint.ToString(); 66 67 Socket sk = new Socket(); 68 69 //加入socket列表 70 socketList.Add(sk); 71 72 nowThread.Start(handler); 73 } 74 } 75 catch (Exception e) 76 { 77 //釋放資源 IIS回收 正常斷開的異常 78 if (e.Message != "一個封鎖操做被對 WSACancelBlockingCall 的調用中斷。") 79 throw e; 80 else 81 throw e; 82 } 83 } 84 85 //public delegate void CallBack(); 86 87 // 接受 客戶端的信息 88 private static void ReceiveClientData(object client) 89 { 90 Socket nowClient = (Socket)client; 91 while (true) 92 { 93 try 94 { 95 int res = 0; 96 byte[] bytes = new byte[1024]; 97 // 不斷的接受客戶端發來的信息, 當客戶端離線後,退出。 98 res = nowClient.Receive(bytes); 99 100 if (res <= 0) 101 { 102 throw new SocketException(); 103 } 104 105 string str = Encoding.UTF8.GetString(bytes, 0, res); 106 107 //綁定ID 業務邏輯 108 if (str.IndexOf("****:****") >= 0) 109 { 110 foreach (var item in socketList) 111 { 112 if (item.RemoteEndPoint == nowClient.RemoteEndPoint) 113 { 114 SendMsg(item.RemoteEndPoint,"SET:(1,2,3)"); 115 break; 116 } 117 } 118 } 119 } 120 catch (SocketException se) 121 { 122 socketList = (from si in socketList where si.RemoteEndPoint != nowClient.RemoteEndPoint select si).ToList(); 123 nowClient.Close(); 124 break; 125 } 126 catch (Exception ee) 127 { 128 throw ee; 129 } 130 } 131 } 132 133 #endregion 134 135 #region 發送數據 136 137 /// <summary> 138 /// 發送數據給客戶端 139 /// </summary> 140 /// <param name="ep">ip和Port</param> 141 /// <param name="msg">發送的消息</param> 142 public static void SendMsg(EndPoint ep, string msg) 143 { 144 try 145 { 146 foreach (var item in socketList) 147 { 148 if (item.listener.RemoteEndPoint == ep) 149 { 150 byte[] data = Encoding.UTF8.GetBytes(msg); 151 item.listener.Send(data); 152 break; 153 } 154 } 155 } 156 catch (Exception ee) 157 { 158 throw ee; 159 } 160 } 161 162 163 #endregion
Global 裏設置 Application_End 函數中 釋放資源ide
1 protected void Application_Start() 2 { 3 4 if (SocketHelper.listenClientThread == null) 5 { 6 SocketHelper.listenClientThread = new Thread(new ThreadStart(SocketHelper.StartListening)); 7 SocketHelper.listenClientThread.IsBackground = true; 8 SocketHelper.listenClientThread.Start(); 9 } 10 11 AreaRegistration.RegisterAllAreas(); 12 RegisterGlobalFilters(GlobalFilters.Filters); 13 RegisterRoutes(RouteTable.Routes); 14 } 15 16 protected void Application_End() 17 { 18 SocketHelper.listener.Close(); 19 SocketHelper.listener.Dispose(); 20 SocketHelper.listenClientThread = null; 21 }
歡迎提出問題 謝謝~~函數