Socket .net MVC 的配置 包括異常斷開

解決問題: 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
View Code

 

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         }
View Code

 

歡迎提出問題 謝謝~~函數

相關文章
相關標籤/搜索