{
private static int myProt = 4502; //socket监听端口
static Thread listenThread;
private static Boolean isConSocket = false;
//日志打印,需要引入log4net,log4net.xml配置存放日志的位置。
private static log4net.ILog Log = LogManager.GetLogger(“MvcApplication”);
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping(“xml”, “true”, “application/xml”));
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue(“text/html”));
RouteConfig.RegisterRoutes(RouteTable.Routes);
//启动socket服务。
StartSocketByConfig();
Thread.Sleep(2000);
//监听socket服务。
Thread socketListen = new Thread(ListenSocketService);
socketListen.Start();
}
public static void StartSocketByConfig()
{
listenThread = new Thread(ListenConnect);
listenThread.Start();
}
/// <summary>
/// 监听客户端连接
/// </summary>
private static void ListenConnect()
{
//socket服务器IP地址
IPAddress ipAddress = IPAddress.Parse(“192.168.3.141”);//绑定IP地址:端口
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, myProt);
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
//设置KeeyAlive,假如客户端不主动发消息时,Tcp本身会发一个心跳包,来通知服务器,这是一个保持通讯的链接。
//避免等到下一次通讯时,才知道链接已经断开。
serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
serverSocket.Bind(localEndPoint);
Log.Debug(String.Format(“启动监听{0}成功\n”, serverSocket.LocalEndPoint.ToString()));
serverSocket.Listen(1); //设定最多1个排队连接请求
isConSocket = true;
Log.Debug(“ListenConnect 开始”+ isConSocket);
Socket socket = null;
int i = 0;
while (true && isConSocket)
{
try
{
//接收连接
if(serverSocket == null)
{
continue;
}
socket = serverSocket.Accept(); //服务第一次启动时,是正常的;原因是异常断开后,通过监听线程再次启动服务后,就卡死在这边,不报异常,也不接收客户端。 问一下是什么原因呢?
socket.ReceiveTimeout = 500;
//接收的数据
StateObject state = new StateObject();
if (socket.Available > 0)
{
socket.Blocking = true;
int bytesRead = socket.Receive(state.buffer, 0, state.buffer.Length, SocketFlags.None);
read(state.buffer, bytesRead);
socket.Shutdown(SocketShutdown.Receive);
}
socket.Close();
socket.Dispose();
}
catch (Exception ex)
{
Log.Debug(“ListenConnect 监听异常!”);
Log.Debug(“ListenConnect===” + ex.ToString(), ex);
try
{
if(socket != null)
{
Log.Debug(“ListenConnect socket!”);
// socket.Disconnect(false);
socket.Close();
socket.Dispose();
}
if(serverSocket != null)
{
Log.Debug(“ListenConnect serverSocket!”);
// serverSocket.Disconnect(false);
serverSocket.Close();
serverSocket.Dispose();
}
}
catch(Exception e)
{
Log.Debug(“ListenConnect 222监听异常!”,e);
}
finally
{
isConSocket = false;
socket = null;
serverSocket = null;
}
}
finally
{
Thread.Sleep(20);
}
}
Log.Debug(“ListenConnect 结束”+ isConSocket);
}
public static void read(byte[] buffer, int bytesRead)
{
try
{
if (bytesRead > 0)
{
//接收的数据
StringBuilder sb = new StringBuilder();
sb.Append(Encoding.ASCII.GetString(buffer, 0, bytesRead));
string content = sb.ToString();
if (content.IndexOf(“\r\n”) > -1 || content.IndexOf(“<EOF>”) > -1 || content.IndexOf(“\0”) > -1)
{
//从百傲瑞达系统接收到的开关门实时事件。
try
{
//businessMethod(content);//业务逻辑
}
catch (Exception ex)
{
Log.Debug(String.Format(“业务逻辑消息异常{0}”, ex.Message));
}
Log.Debug(String.Format(“接收客户端的消息{0}”, content));
}
}
}
catch (Exception ex)
{
Log.Debug(“接收客户端的消息异常.”);
Log.Debug(“ReadCallback===” + ex.ToString());
}
}
void Application_End(object sender, EventArgs e)
{
listenThread.Abort();
isConSocket = false;
}
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
listenThread.Abort();
}
/// <summary>
/// 监听服务能否正常,socket服务断开则重启
/// </summary>
private static void ListenSocketService()
{
while (true)
{
try
{
if ( !isConSocket) //IsSocketConnected(serverSocket) &&
{
Log.Debug(“socket 服务重新启动\n”);
listenThread.Abort();
StartSocketByConfig();
}
}
catch (Exception ex)
{
Log.Debug(“socket 服务启动异常\n”);
Log.Debug(“ListenSocketService===” + ex.ToString());
}
Thread.Sleep(100);
}
}
///
/// 判断connected的方法,但未检测对端网线断开或ungraceful的情况
///
public static bool IsSocketConnected(Socket s)
{
return (s == null || !s.Connected);
}
}
public class StateObject
{
//client socket
public Socket workSocket = null;
//接收的长度
public const int BufferSize = 1024 * 50;
//接收的数据
public byte[] buffer = new byte[BufferSize];
//接收的数据
public StringBuilder sb = new StringBuilder();
}
}
10
有 while语句的,基本上都是入门时的简单例子。而有sleep语句的,可以断定是坑人的代码。
10
1、异常断开….这个作为服务端遇到异常也不能让他断开吧/
2、异常后while (true && isConSocket)的这个判断, isConSocket重置没?
3、 socket = serverSocket.Accept()最好每个连接客户端都开一个线程来处理
20
但是假如你是要用这个来做具体的项目的话,是不行的。
你要学会用异步和事件来处理客户端接入,数据收发。
而不是一味的在那while、sleep。