using HslCommunication.Core; using HslCommunication.Core.Net; using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; namespace HslCommunication.Enthernet { /// <summary> /// 通用设备的基础网络信息 /// </summary> public class DeviceNet : NetworkServerBase { #region Constructor /// <summary> /// 实例化一个通用的设备类 /// </summary> public DeviceNet() { list = new List<DeviceState>(); lock_list = new SimpleHybirdLock(); } #endregion #region Connection Management private List<DeviceState> list; // 所有客户端的连接对象 private SimpleHybirdLock lock_list; // 列表锁 private void AddClient(DeviceState device) { lock_list.Enter(); list.Add(device); lock_list.Leave(); ClientOnline?.Invoke(device); } private void RemoveClient(DeviceState device) { lock_list.Enter(); list.Remove(device); device.WorkSocket?.Close(); lock_list.Leave(); ClientOffline?.Invoke(device); } #endregion #region Event Handle /// <summary> /// 当客户端上线的时候,触发此事件 /// </summary> public event Action<DeviceState> ClientOnline; /// <summary> /// 当客户端下线的时候,触发此事件 /// </summary> public event Action<DeviceState> ClientOffline; /// <summary> /// 按照ASCII文本的方式进行触发接收的数据 /// </summary> public event Action<DeviceState, string> AcceptString; /// <summary> /// 按照字节的方式进行触发接收的数据 /// </summary> public event Action<DeviceState, byte[]> AcceptBytes; #endregion #region Private Member private readonly byte endByte = 0x0D; // 结束的指令 #endregion /// <summary> /// 当接收到了新的请求的时候执行的操作 /// </summary> /// <param name="socket">异步对象</param> /// <param name="endPoint">终结点</param> protected override void ThreadPoolLogin(Socket socket, IPEndPoint endPoint) { // 登录成功 DeviceState stateone = new DeviceState() { WorkSocket = socket, DeviceEndPoint = (IPEndPoint)socket.RemoteEndPoint, IpAddress = ((IPEndPoint)socket.RemoteEndPoint).Address.ToString(), ConnectTime = DateTime.Now, }; AddClient(stateone); try { stateone.WorkSocket.BeginReceive(stateone.Buffer, 0, stateone.Buffer.Length, SocketFlags.None, new AsyncCallback(ContentReceiveCallBack), stateone); } catch (Exception ex) { //登录前已经出错 RemoveClient(stateone); LogNet?.WriteException(ToString(), StringResources.Language.NetClientLoginFailed, ex); } } private void ContentReceiveCallBack(IAsyncResult ar) { if (ar.AsyncState is DeviceState stateone) { try { int count = stateone.WorkSocket.EndReceive(ar); if (count > 0) { MemoryStream ms = new MemoryStream(); byte next = stateone.Buffer[0]; while (next != endByte) { ms.WriteByte(next); byte[] buffer = new byte[1]; stateone.WorkSocket.Receive(buffer, 0, 1, SocketFlags.None); next = buffer[0]; } // 接收完成 stateone.WorkSocket.BeginReceive(stateone.Buffer, 0, stateone.Buffer.Length, SocketFlags.None, new AsyncCallback(ContentReceiveCallBack), stateone); byte[] receive = ms.ToArray(); ms.Dispose(); lock_list.Enter(); stateone.ReceiveTime = DateTime.Now; lock_list.Leave(); AcceptBytes?.Invoke(stateone, receive); AcceptString?.Invoke(stateone, Encoding.ASCII.GetString(receive)); } else { RemoveClient(stateone); LogNet?.WriteInfo(ToString(), StringResources.Language.NetClientOffline); } } catch (Exception ex) { //登录前已经出错 RemoveClient(stateone); LogNet?.WriteException(ToString(), StringResources.Language.NetClientLoginFailed, ex); } } } } }