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

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         }

有细节上稍许不对 欢迎提出问题 谢谢~~

时间: 2024-10-14 20:16:44

Socket .net MVC 的配置 包括异常断开的相关文章

socket选项自带的TCP异常断开检测

TCP异常断开是指在突然断电,直接拔网线等等情况下,如果通信双方没有进行数据发送通信等处理的时候,无法获知连接已经断开的情况. 在通常的情况下,为了使得socket通信不受操作系统的限制,需要自己在应用层实现心跳包机制,来检查异常断开的情况,一般的方式就是服务器在一段时间没有收到客户端数据包时,定时发包,然后客户端回应,如果已经出现异常断开则服务器接收会返回错误,而客户端在指定时间内没有收到数据包,则主动向服务器发包,得到错误就说明断开.诸如此类的方式就是自己实现的心跳包机制. 但操作系统本身也

(转)TCP连接异常断开检测

TCP是一种面向连接的协议,连接的建立和断开需要通过收发相应的分节来实现.某些时候,由于网络的故障或是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接.下面介绍一种方法来检测这种异常断开的情况 TAG: TCP连接异常断开  TCP断链 TCP是一种面向连接的协议,连接的建立和断开需要通过收发相应的分节来实现.某些时候,由于网络的故障或是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接.下面介绍一种方法来检测这种异常断开的情况 1) 在TCP协议中提供了KEEPA

Maven 工程下 Spring MVC 站点配置 (三) C3P0连接池与@Autowired的应用

Maven 工程下 Spring MVC 站点配置 (一) Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作 前两篇文章主要是对站点和数据库操作配置进行了演示,如果单单实现这两个需求的话,那么基本足够,但是很多时候一个网站除了仅仅能够访问数据库是不够的,它还需要对性能以及更简化的步骤有着更多的要求,这一篇重点就是帮助我们如何去实现数据连接池管理与更简化便利的开发步骤. 如果你觉得自己能写出更高效率的连接池,那你可以不需要这篇文章了,我更建议你可以去开源组织毛遂自

Spring MVC 事务配置

Spring MVC事务配置 要了解事务配置的所有方法,请看一下<Spring事务配置的5种方法> 本文介绍两种配置方法: 一.      XML,使用tx标签配置拦截器实现事务 一.      Annotation方式 以下所使用环境为Spring4.0.3.Hibernate4.3.5 一.      XML,使用tx标签配置拦截器实现事务 Entity类User.java,持久化类,对应数据库表user package com.lei.demo.entity; import javax.

spring原拦截器配置与新命名空间mvc:interceptors配置拦截器对照与注意事项

原先,我们是这么配置拦截器的 <bean id="openSessionInViewInterceptor"class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"> <property name="sessionFactory" ref="sessionFactory" /> </bean>

[转]Spring MVC 事务配置

Spring MVC事务配置 要了解事务配置的所有方法,请看一下<Spring事务配置的5种方法> 本文介绍两种配置方法:  <tx:advice/>就是告诉事务管理器:怎么做.如何去执行.通过什么方法(形式)去执行. 一.      XML,使用tx标签配置拦截器实现事务 一.      Annotation方式 以下所使用环境为Spring4.0.3.Hibernate4.3.5 一.      XML,使用tx标签配置拦截器实现事务 Entity类User.java,持久化类

spring原拦截器配置与新命名空间mvc:interceptors配置拦截器对比与注意事项

原先,我们是这么配置拦截器的 <bean id="openSessionInViewInterceptor"class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"> <property name="sessionFactory" ref="sessionFactory" /> </bean>

ASP.NET MVC 3 配置EF自动生成模型

Tools(工具) =>  扩展工具 => Nuget Tools(工具) => Nuget=>程序包管理器控制台 Nuget 程序包管理器 => Install-Package EntityFramework  (为了安装Efcodefirst) EFCodeFirst => entity framework.dll(控制器用到EF的时候需要添加引用 ,目前版本是6.1) EfPowerTools => 模型生成器 类 => 右键 => entity

Spring MVC注解配置结合Hibernate的入门教程及其代码实例

原文:Spring MVC注解配置结合Hibernate的入门教程及其代码实例 源代码下载地址:http://www.zuidaima.com/share/1787210045197312.htm 1.概述 本文旨在搭建Spring MVC+Hibernate开发框架,通过一个简单的demo讲解Spring MVC的相关配置文件,以及通过注解方式实现简单功能. 开发框架:Spring+Spring MVC+Hibernate(Spring所用的版本为3.0.5). 数据库:MySQL(数据库名称