zoukankan      html  css  js  c++  java
  • Socket .net MVC 的配置 包括异常断开

    解决问题: 1. Socket 的异常断开 

         2. 部署在IIS程序池上的程序回收导致 端口占用,对象资源却已经释放的BUG

        

    SocketHelper 类   inOptionValues .net框架中用于检测连接的客户端 检测时间(默认2小时)   或者自己写个心跳包(客户端和服务端用规定协议)   

      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 函数中 释放资源

     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

    欢迎提出问题 谢谢~~

    眼界决定目标、

                   ----生命本没有意义,只在于你追求的东西!


     

  • 相关阅读:
    数据库Connection.OPEN()异常情况下 耗时很久才回应
    System.Threading.Tasks.TaskExceptionHolder.Finalize() 系统错误c#
    WCF双向通讯netTCP
    并行LINQ PLinq
    winform调用http
    kindle电子书的资源网站
    vscode设置中文语言
    Python拼接路径
    Python查看已安装模块
    Python查看模块版本
  • 原文地址:https://www.cnblogs.com/bivozeou/p/4341679.html
Copyright © 2011-2022 走看看