| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124 |
-
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Net;
- using System.Net.Sockets;
- using System.Text;
- using System.Threading;
- using System.Windows.Forms;
- using Curtain.Net.Sockets.PLC.Model;
- namespace Curtain.Net.Sockets.PLC
- {
- /// <summary>
- /// Socket 服务端
- /// </summary>
- public class SocketServer : PLCSocket
- {
- /// <summary>
- /// 在线客户端
- /// </summary>
- //private Dictionary<ClientSession, IServerModel> _factory = new Dictionary<Type, IServerModel>();
- protected Dictionary<string, ClientSession> clients = new Dictionary<string, ClientSession>();
- #region 属性
- /// <summary>
- /// 服务所在winform窗体(异步事件响应用)
- /// </summary>
- public Control OwnerForm
- {
- get;
- set;
- }
- /// <summary>
- /// 服务状态
- /// </summary>
- public bool Started
- {
- get;
- protected set;
- }
- /// <summary>
- /// 服务端模型
- /// </summary>
- public virtual IServerModel Model
- {
- get
- {
- return null;
- }
- }
- /// <summary>
- /// 通信超时(毫秒)
- /// </summary>
- public int ReceiveTimeout
- {
- get; set;
- }
- /// <summary>
- /// 通信超时(毫秒)
- /// </summary>
- public int SendTimeout
- {
- get; set;
- }
- /// <summary>
- /// 服务端Session
- /// </summary>
- public ServerSession ServerSession
- {
- get;
- protected set;
- }
- /// <summary>
- /// 接收服务启动异常后自动重试次数
- /// </summary>
- private int _repeated = 3;
- /// <summary>
- /// 接收服务启动异常后自动重试次数(默认3次,最大20次)
- /// </summary>
- public int Repeated
- {
- get
- {
- return _repeated;
- }
- set
- {
- if (value < 0)
- {
- _repeated = 0;
- }
- else if (value > 20)
- {
- _repeated = 20;
- }
- else
- {
- _repeated = value;
- }
- }
- }
- #endregion
- #region 构造
- /// <summary>
- /// Socket 服务端
- /// </summary>
- public SocketServer()
- {
- }
- #endregion
- #region 事件
- /// <summary>
- /// 服务启动前
- /// </summary>
- public event CancelEventHandler ServerStarting;
- /// <summary>
- /// 服务启动后
- /// </summary>
- public event CancelEventHandler ServerStoping;
- /// <summary>
- /// 服务停止前
- /// </summary>
- public event EventHandler ServerStarted;
- /// <summary>
- /// 服务停止后
- /// </summary>
- public event EventHandler ServerStoped;
- /// <summary>
- /// 服务端事件发生
- /// </summary>
- public event ServerMessageEventHandler ServerMessage;
- /// <summary>
- /// 服务启动前
- /// </summary>
- protected virtual void OnServerStarting(CancelEventArgs e)
- {
- ServerStarting?.Invoke(this, e);
- }
- /// <summary>
- /// 服务启动后
- /// </summary>
- protected virtual void OnServerStoping(CancelEventArgs e)
- {
- ServerStoping?.Invoke(this, e);
- }
- /// <summary>
- /// 服务停止前
- /// </summary>
- protected virtual void OnServerStarted(EventArgs e)
- {
- ServerStarted?.Invoke(this, e);
- }
- /// <summary>
- /// 服务停止后
- /// </summary>
- protected virtual void OnServerStoped(EventArgs e)
- {
- ServerStoped?.Invoke(this, e);
- }
- /// <summary>
- /// 服务端事件发生
- /// </summary>
- protected virtual void OnServerMessage(ServerMessageEventArgs e)
- {
- if (OwnerForm?.InvokeRequired ?? false)
- {
- OwnerForm.BeginInvoke(new Action<ServerMessageEventArgs>(OnServerMessage), e);
- return;
- }
- ServerMessage?.Invoke(this, e);
- }
- /// <summary>
- /// 完成数据接收
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- public delegate void ReceivedEventHandler(object sender, ReceiveSession e);
- /// <summary>
- /// 完成数据接收
- /// </summary>
- public event ReceivedEventHandler Received;
- /// <summary>
- /// 完成数据接收
- /// </summary>
- /// <param name="rs"></param>
- protected virtual void OnReceived(ReceiveSession rs)
- {
- //Framework.Log.Logger.Debug("OnReceived", "timeout");
- if (OwnerForm?.InvokeRequired ?? false)
- {
- OwnerForm.BeginInvoke(new Action<ReceiveSession>(OnReceived), rs);
- return;
- }
- Received?.Invoke(this, rs);
- }
- #endregion
- #region Accept
- /// <summary>
- /// 开始接收客户端消息
- /// </summary>
- /// <param name="iar"></param>
- protected void AcceptCallback(IAsyncResult iar)
- {
- if (!this.Started || this.Socket == null)
- {
- // 服务器已停止
- return;
- }
- if (iar.AsyncState is ServerSession ss)
- {
- if (ss == null || ss.Socket == null)
- {
- // 服务已停止
- return;
- }
- Socket clientSocket = null;
- ClientSession cs = new ClientSession();
- clients.Add(cs.ID, cs);
- try
- {
- clientSocket = ss.Socket.EndAccept(iar);
- cs.Server = ss;
- cs.Socket = clientSocket;
- try
- {
- cs.IPEndPoint = (IPEndPoint)clientSocket.RemoteEndPoint;
- }
- catch (Exception ex)
- {
- ServerMessageEventArgs e1 = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Debug,
- Code = "CNS-D-001",
- Message = "客户端IP异常",
- Exception = ex,
- Client = cs,
- Server = ss
- };
- this.OnServerMessage(e1);
- }
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Trace,
- Code = "CNS-T-000",
- Message = $"客户端 {cs} 已连接",
- Client = cs,
- Server = ss
- };
- this.OnServerMessage(e);
- ThreadPool.QueueUserWorkItem(new WaitCallback(OnClientConnected), cs);
- }
- catch (ObjectDisposedException ex)
- {
- // 服务已停止
- OnServerDownError(ss, ex);
- return;
- }
- catch (Exception ex)
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Error,
- Code = "CNS-E-000",
- Message = "客户端已关闭",
- Exception = ex,
- Client = cs,
- Server = ss
- };
- this.OnServerMessage(e);
- //clientSocket?.Close();
- CloseClientSocket(cs);
- }
- //如果失败,尝试重新启动
- int i = 0;
- while (i < _repeated)
- {
- try
- {
- ss.Socket.BeginAccept(new AsyncCallback(AcceptCallback), ss);
- break;
- }
- catch (Exception ex)
- {
- i++;
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Error,
- Code = "CNS-E-001",
- Message = "服务启动失败,尝试重启( " + i + " / " + _repeated + " )",
- Exception = ex,
- Server = ss
- };
- this.OnServerMessage(e);
- Thread.Sleep(1000);
- }
- }
- if (i >= _repeated)
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Error,
- Code = "CNS-E-002",
- Message = "服务尝试重启失败",
- //e.Exception = ex;
- Server = ss
- };
- this.OnServerMessage(e);
- this.StopCore();
- }
- }
- }
- /// <summary>
- /// 开始接收
- /// </summary>
- /// <param name="cs"></param>
- protected virtual void StartReceive(ClientSession cs)
- {
- if (!(cs.Socket.Connected))
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Trace,
- Code = "CNS-T-002",
- Message = $"客户端 {cs} 已关闭",
- Client = cs,
- Server = cs.Server
- };
- this.OnServerMessage(e);
- return;
- }
- int length = Model.HeadLength;
- if (length < 1)
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Error,
- Code = "CNS-E-003",
- Message = Model.GetType().ToString() + ".HeadLength<1",
- Client = cs,
- Server = cs.Server
- };
- this.OnServerMessage(e);
- return;
- }
- ReceiveSession rs = new ReceiveSession
- {
- ServerSocket = this,
- Client = cs,
- Offset = 0,
- Size = length
- };
- try
- {
- rs.HeadBytes = new byte[length];
- //cs.Socket.ReceiveTimeout = 0;//this.ReceiveTimeout;
- //Framework.Log.Logger.Debug("StartReceive", "timeout");
- cs.Socket.BeginReceive(rs.HeadBytes, rs.Offset, rs.Size, SocketFlags.None,
- HeadReceiveCallback, rs);
- }
- catch (Exception ex)
- {
- //OnReceiveException(rs, ex);
- OnClientDown(rs, ex);
- }
- }
- /// <summary>
- /// 指令头接收方法
- /// </summary>
- /// <param name="ar">异步状态信息</param>
- protected virtual void HeadReceiveCallback(IAsyncResult ar)
- {
- if (!this.Started || this.Socket == null)
- {
- // 服务器已停止
- return;
- }
- //Framework.Log.Logger.Debug("HeadReceiveCallback=0", "timeout");
- if (ar.AsyncState is ReceiveSession rs)
- {
- if (rs.Client == null || rs.Client.Socket == null)
- {
- // 服务器已停止
- return;
- }
- try
- {
- int receiveCount = rs.Client.Socket.EndReceive(ar);
- //Framework.Log.Logger.Debug("HeadReceiveCallback-1:receiveCount="+ receiveCount, "timeout");
- if (receiveCount == 0)
- {
- if (rs.Offset > 0)
- {
- OnClientTimeout(rs);
- }
- else
- {
- OnClientDown(rs);
- }
- return;
- }
- else
- {
- rs.Offset += receiveCount;
- }
- }
- catch (ObjectDisposedException)
- {
- // 客户端Socket已关闭(接收超时)
- //OnReceiveTimeout(rs);
- // 服务已停止
- //OnServerDownError(rs.Client.Server, ex);
- return;
- }
- catch (SocketException ex)
- {
- // 已经断开连接了
- //OnReceiveException(rs, ex);
- OnClientDown(rs, ex);
- return;
- }
- catch (Exception ex)
- {
- OnReceiveException(rs, ex, true);
- return;
- }
- if (rs.Offset < rs.Size)
- {
- try
- {
- // 继续接收,超时重启
- //Framework.Log.Logger.Debug("HeadReceiveCallback-2:继续接收,超时重启", "timeout");
- //rs.Client.Socket.ReceiveTimeout = this.ReceiveTimeout;
- //rs.Client.Socket.BeginReceive(rs.HeadBytes, rs.Offset, rs.Size - rs.Offset,
- // SocketFlags.None, HeadReceiveCallback, rs);
- rs.Client.Socket.BeginReceiveByTimeout(rs.HeadBytes, rs.Offset, rs.Size - rs.Offset, SocketFlags.None,
- HeadReceiveCallback, HeadReceiveCallbackTimeout, this.ReceiveTimeout, rs);
- }
- catch (Exception ex)
- {
- //OnReceiveException(rs, ex);
- OnClientDown(rs, ex);
- }
- return;
- }
- try
- {
- //rs.Head = ServerModel.ToCommandFromReceive(rs.HeadBytes);
- // 验证数据头
- if (!Model.CheckHead(rs))
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Warning,
- Code = "CNS-W-000",
- Message = "接收的数据头格式不正确",
- Client = rs.Client,
- Server = rs.Client.Server
- };
- CloseClientSocket(rs);
- this.OnServerMessage(e);
- return;
- }
- if (Model.FormatType == CommandFormatType.StartStopChar)
- {
- StringBuilder sbContent = new StringBuilder();
- bool isEscapeChar = false;
- List<byte> listByte = new List<byte>();
- try
- {
- while (true)
- {
- byte[] bytes = new byte[1];
- rs.Client.Socket.ReceiveTimeout = this.ReceiveTimeout;
- int receiveCount = rs.Client.Socket.Receive(bytes, 0, 1, SocketFlags.None);
- if (receiveCount == 0)
- {
- OnClientDown(rs);
- return;
- }
- char[] chars = Encoding.ASCII.GetChars(bytes);
- if (!isEscapeChar)
- {
- if (chars[0] == this.Model.EscapeChar)
- {
- isEscapeChar = true;
- continue;
- }
- if (chars[0] == this.Model.StopChar)
- {
- break;
- }
- }
- isEscapeChar = false;
- listByte.AddRange(bytes);
- sbContent.Append(chars[0]);
- }
- rs.ContentBytes = listByte.ToArray();
- rs.Content = sbContent.ToString();
- StartReceive(rs.Client);
- OnReceived(rs);
- }
- catch (Exception ex)
- {
- OnClientDown(rs, ex);
- }
- return;
- }
- int length = Model.GetContentLength(rs);
- if (length > 0)
- {
- rs.Offset = 0;
- rs.Size = length;
- try
- {
- rs.ContentBytes = new byte[length];
- // 正文接收,超时重启
- //Framework.Log.Logger.Debug("HeadReceiveCallback-3:Content="+ length, "timeout");
- //rs.Client.Socket.ReceiveTimeout = this.ReceiveTimeout;
- //rs.Client.Socket.BeginReceive(rs.ContentBytes, rs.Offset, rs.Size,
- // SocketFlags.None, ContentReceiveCallback, rs);
- rs.Client.Socket.BeginReceiveByTimeout(rs.ContentBytes, rs.Offset, rs.Size, SocketFlags.None,
- ContentReceiveCallback, ContentReceiveCallbackTimeout, this.ReceiveTimeout, rs);
- }
- catch (Exception ex)
- {
- //OnReceiveException(rs, ex);
- OnClientDown(rs, ex);
- }
- }
- else if (length < 0)
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Warning,
- Code = "CNS-W-001",
- Message = "接收的数据头格式不正确(文本长度)",
- Client = rs.Client,
- Server = rs.Client.Server
- };
- CloseClientSocket(rs);
- this.OnServerMessage(e);
- }
- else
- {
- StartReceive(rs.Client);
- OnReceived(rs);
- }
- }
- catch (Exception ex)
- {
- OnReceiveException(rs, ex);
- }
- }
- }
- /// <summary>
- /// 消息头接收超时
- /// </summary>
- /// <param name="ar"></param>
- protected virtual void HeadReceiveCallbackTimeout(IAsyncResult ar)
- {
- if (!this.Started || this.Socket == null)
- {
- // 服务器已停止
- return;
- }
- //Framework.Log.Logger.Debug("HeadReceiveCallbackTimeout:头接收超时", "timeout");
- if (ar.AsyncState is ReceiveSession rs)
- {
- if (rs.Client == null || rs.Client.Socket == null)
- {
- // 服务器已停止
- return;
- }
- OnReceiveTimeout(rs, true);
- }
- }
- /// <summary>
- /// 数据内容接收方法
- /// </summary>
- /// <param name="ar"></param>
- protected virtual void ContentReceiveCallback(IAsyncResult ar)
- {
- if (!this.Started || this.Socket == null)
- {
- // 服务器已停止
- return;
- }
- //Framework.Log.Logger.Debug("ContentReceiveCallback=0", "timeout");
- if (ar.AsyncState is ReceiveSession rs)
- {
- if (rs.Client == null || rs.Client.Socket == null)
- {
- // 服务器已停止
- return;
- }
- try
- {
- int receiveCount = rs.Client.Socket.EndReceive(ar);
- //Framework.Log.Logger.Debug("ContentReceiveCallback-1:receiveCount=" + receiveCount, "timeout");
- if (receiveCount == 0)
- {
- if (rs.Offset > 0)
- {
- OnClientTimeout(rs);
- }
- else
- {
- OnClientDown(rs);
- }
- return;
- }
- else
- {
- rs.Offset += receiveCount;
- }
- }
- catch (ObjectDisposedException)
- {
- // 客户端Socket已关闭(接收超时)
- //OnReceiveTimeout(rs);
- // 服务已停止
- //OnServerDownError(rs.Client.Server, ex);
- return;
- }
- catch (SocketException ex)
- {
- // 已经断开连接了
- //OnReceiveException(rs, ex);
- OnClientDown(rs, ex);
- return;
- }
- catch (Exception ex)
- {
- OnReceiveException(rs, ex, true);
- return;
- }
- if (rs.Offset < rs.Size)
- {
- try
- {
- // 继续接收,超时重启
- //Framework.Log.Logger.Debug("ContentReceiveCallback-2:继续接收,超时重启", "timeout");
- //rs.Client.Socket.ReceiveTimeout = this.ReceiveTimeout;
- //rs.Client.Socket.BeginReceive(rs.ContentBytes, rs.Offset, rs.Size - rs.Offset,
- // SocketFlags.None, ContentReceiveCallback, rs);
- rs.Client.Socket.BeginReceiveByTimeout(rs.ContentBytes, rs.Offset, rs.Size - rs.Offset, SocketFlags.None,
- ContentReceiveCallback, ContentReceiveCallbackTimeout, this.ReceiveTimeout, rs);
- }
- catch (Exception ex)
- {
- //OnReceiveException(rs, ex);
- OnClientDown(rs, ex);
- }
- return;
- }
- rs.Content = Model.ToContentFromReceive(rs.ContentBytes);
- StartReceive(rs.Client);
- OnReceived(rs);
- }
- }
- /// <summary>
- /// 数据内容接收超时
- /// </summary>
- /// <param name="ar"></param>
- protected virtual void ContentReceiveCallbackTimeout(IAsyncResult ar)
- {
- if (!this.Started || this.Socket == null)
- {
- // 服务器已停止
- return;
- }
- //Framework.Log.Logger.Debug("ContentReceiveCallbackTimeout:正文接收超时", "timeout");
- if (ar.AsyncState is ReceiveSession rs)
- {
- if (rs.Client == null || rs.Client.Socket == null)
- {
- // 服务器已停止
- return;
- }
- OnReceiveTimeout(rs, false);
- }
- }
- #endregion
- #region 事件处理
- /// <summary>
- /// 客户端上线
- /// </summary>
- /// <param name="state">session</param>
- protected virtual void OnClientConnected(object state)
- {
- if (state is ClientSession cs)
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Trace,
- Code = "CNS-T-001",
- Message = $"客户端 {cs} 已准备",
- Client = cs,
- Server = cs.Server
- };
- this.OnServerMessage(e);
- this.StartReceive(cs);
- }
- }
- /// <summary>
- /// 服务接收异常
- /// </summary>
- /// <param name="rs"></param>
- /// <param name="ex">异常信息</param>
- /// <param name="restart">异常信息</param>
- protected virtual void OnReceiveException(ReceiveSession rs, Exception ex, bool restart = false)
- {
- if (restart)
- {
- // 重启接收
- StartReceive(rs.Client);
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Error,
- Code = "CNS-E-004",
- Message = $"服务端接收异常,重启客户端 {rs.Client} 连接",
- Exception = ex,
- Client = rs.Client,
- Server = rs.Client.Server
- };
- this.OnServerMessage(e);
- }
- else
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Error,
- Code = "CNS-E-005",
- Message = $"服务端接收异常,关闭客户端 {rs.Client} 连接",
- Exception = ex,
- Client = rs.Client,
- Server = rs.Client.Server
- };
- CloseClientSocket(rs);
- this.OnServerMessage(e);
- }
- }
- /// <summary>
- /// 客户端下线
- /// </summary>
- /// <param name="rs"></param>
- /// <param name="ex"></param>
- protected virtual void OnClientDown(ReceiveSession rs, Exception ex = null)
- {
- //Framework.Log.Logger.Debug("OnClientDown", "timeout");
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Trace,
- Client = rs.Client,
- Server = rs.Client.Server
- };
- if (ex == null)
- {
- e.Code = "CNS-T-003";
- e.Message = $"客户端 {rs.Client} 已下线";
- }
- else
- {
- e.Code = "CNS-T-004";
- e.Message = $"客户端 {rs.Client} 已下线(异常)";
- e.Exception = ex;
- }
- CloseClientSocket(rs);
- this.OnServerMessage(e);
- }
- private void CloseClientSocket(ClientSession cs)
- {
- cs?.Socket?.Close();
- cs?.Clear();
- clients.Remove(cs.ID);
- }
- private void CloseClientSocket(ReceiveSession rs)
- {
- CloseClientSocket(rs.Client);
- }
- /// <summary>
- /// 客户端发送超时
- /// </summary>
- /// <param name="rs"></param>
- protected virtual void OnClientTimeout(ReceiveSession rs)
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Trace,
- Code = "CNS-T-005",
- Message = $"客户端 {rs.Client} 发送超时",
- Client = rs.Client,
- Server = rs.Client.Server
- };
- this.OnServerMessage(e);
- }
- /// <summary>
- /// 服务接收超时
- /// </summary>
- /// <param name="rs"></param>
- /// <param name="isHead"></param>
- protected virtual void OnReceiveTimeout(ReceiveSession rs, bool isHead)
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Trace,
- Code = "CNS-T-006",
- Message = $"接收客户端 {rs.Client} {(isHead ? "报文头" : "报文内容")}超时",
- Client = rs.Client,
- Server = rs.Client.Server
- };
- //StartReceive(rs.Client);
- CloseClientSocket(rs);
- this.OnServerMessage(e);
- }
- /// <summary>
- /// 服务端异常下线
- /// </summary>
- /// <param name="ss"></param>
- /// <param name="ex"></param>
- protected virtual void OnServerDownError(ServerSession ss, Exception ex)
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Debug,
- Code = "CNS-D-000",
- Message = "服务端已关闭",
- Exception = ex,
- Server = ss
- };
- this.OnServerMessage(e);
- }
- /// <summary>
- /// 回复消息
- /// </summary>
- /// <param name="rs"></param>
- /// <param name="message"></param>
- protected internal virtual void ReturnMessage(ReceiveSession rs, string message)
- {
- //Framework.Log.Logger.Debug("SetMessage", "timeout");
- if (rs.Client == null || rs.Client.Socket == null)
- {
- // TO Message?
- return;
- }
- byte[] bs = Model.ToSendFromCommand(message);
- if (bs != null && bs.Length > 0)
- {
- try
- {
- rs.Client.Socket.SendTimeout = this.SendTimeout;
- rs.Client.Socket.Send(bs);
- }
- //catch (ObjectDisposedException ex)
- //{
- // // 客户端Socket已关闭(接收超时)
- // //OnReceiveTimeout(rs);
- // // 服务已停止
- // //OnServerDownError(rs.Client.Server, ex);
- // return;
- //}
- catch (SocketException ex)
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Trace,
- Code = "CNS-T-007",
- Message = $"发送客户端 {rs.Client} [{message}] 超时",
- Client = rs.Client,
- Server = rs.Client?.Server,
- Exception = ex
- };
- this.OnServerMessage(e);
- }
- catch (Exception ex)
- {
- ServerMessageEventArgs e = new ServerMessageEventArgs
- {
- Type = ServerMessageType.Trace,
- Code = "CNS-T-008",
- Message = $"发送客户端 {rs.Client} [{message}] 异常",
- Client = rs.Client,
- Server = rs.Client?.Server,
- Exception = ex
- };
- this.OnServerMessage(e);
- }
- }
- }
- #endregion
- #region Start & Stop
- /// <summary>
- /// 启动服务
- /// </summary>
- /// <param name="port">端口号</param>
- public virtual void Start(int port)
- {
- Start(port, null);
- }
- /// <summary>
- /// 启动服务
- /// </summary>
- /// <param name="port">端口号</param>
- /// <param name="backlog">挂起连接队列的最大长度</param>
- public virtual void Start(int port, int backlog)
- {
- Start(port, null, backlog);
- }
- /// <summary>
- /// 启动服务
- /// </summary>
- /// <param name="port">端口号</param>
- /// <param name="ipAddress">IP地址</param>
- /// <param name="backlog">挂起连接队列的最大长度</param>
- public virtual void Start(int port, IPAddress ipAddress, int backlog = 100)
- {
- if (!Started)
- {
- CancelEventArgs e = new CancelEventArgs();
- this.OnServerStarting(e);
- if (e.Cancel)
- {
- return;
- }
- IPEndPoint ipEndPoint = new IPEndPoint(ipAddress ?? IPAddress.Any, port);
- ServerSession ss = new ServerSession
- {
- IPEndPoint = ipEndPoint,
- Backlog = backlog,
- };
- this.CreateSocket();
- //this.Socket.ReceiveTimeout = this.ReceiveTimeout;
- this.Socket.Bind(ipEndPoint);
- this.Socket.Listen(ss.Backlog);
- ss.Socket = this.Socket;
- //AcceptResult = this.Socket.BeginAccept(new AsyncCallback(AcceptCallback), ss);
- this.Socket.BeginAccept(new AsyncCallback(AcceptCallback), ss);
- this.Started = true;
- this.ServerSession = ss;
- this.OnServerStarted(EventArgs.Empty);
- }
- }
- //IAsyncResult AcceptResult = null;
- /// <summary>
- /// 关闭服务器的引擎
- /// </summary>
- public virtual void Stop()
- {
- if (Started)
- {
- CancelEventArgs e = new CancelEventArgs();
- this.OnServerStoping(e);
- if (e.Cancel)
- {
- return;
- }
- this.StopCore();
- }
- }
- /// <summary>
- /// 停止服务
- /// </summary>
- protected virtual void StopCore()
- {
- this.ServerSession?.Clear();
- this.ServerSession = null;
- this.Started = false;
- this.Close();
- this.Socket = null;
- //this.Socket.EndAccept(AcceptResult);
- foreach (ClientSession item in clients.Values)
- {
- item.Socket?.Close();
- item.Clear();
- }
- clients.Clear();
- this.OnServerStoped(EventArgs.Empty);
- }
- /// <summary>
- /// 销毁
- /// </summary>
- public override void Dispose()
- {
- try
- {
- this.StopCore();
- }
- catch
- {
- }
- base.Dispose();
- }
- #endregion
- }
- /// <summary>
- /// Socket 服务端
- /// </summary>
- public class SocketServer<TServerModel> : SocketServer
- where TServerModel : IServerModel, new()
- {
- #region 属性
- /// <summary>
- /// 服务端模型
- /// </summary>
- public override IServerModel Model
- {
- get
- {
- return this.ServerModel as IServerModel;
- }
- }
- /// <summary>
- /// 服务端模型
- /// </summary>
- public TServerModel ServerModel
- {
- get; protected set;
- }
- #endregion
- #region 构造
- /// <summary>
- /// Socket 服务端
- /// </summary>
- public SocketServer(bool newModel = false)
- {
- if (newModel)
- {
- ServerModel = new TServerModel();
- }
- else
- {
- ServerModel = PLC.Model.ServerModel.CreateModel<TServerModel>();
- }
- this.ReceiveTimeout = this.ServerModel.ReceiveTimeout;
- this.SendTimeout = this.ServerModel.SendTimeout;
- }
- /// <summary>
- /// Socket 服务端
- /// </summary>
- /// <param name="model">新实例</param>
- public SocketServer(TServerModel model)
- {
- if (model == null)
- {
- throw new NullReferenceException("ServerSocket TServerModel");
- }
- ServerModel = model;
- this.ReceiveTimeout = this.ServerModel.ReceiveTimeout;
- this.SendTimeout = this.ServerModel.SendTimeout;
- }
- #endregion
- }
- }
|