usingHslCommunication.BasicFramework;usingHslCommunication.Core;usingHslCommunication.Core.IMessage;usingHslCommunication.Core.Net;usingSystem;usingSystem.Collections.Generic;#if!NETSTANDARD2_0usingSystem.IO.Ports;#endifusingSystem.Net.Sockets;usingSystem.Text;namespaceHslCommunication.Profinet.LSIS{///<summary>///LSisServer///</summary>publicclassLSisServer:NetworkDataServerBase{#regionConstructor///<summary>///LSisServer///</summary>publicLSisServer(){pBuffer=newSoftBuffer(DataPoolLength);qBuffer=newSoftBuffer(DataPoolLength);mBuffer=newSoftBuffer(DataPoolLength);dBuffer=newSoftBuffer(DataPoolLength);WordLength=2;ByteTransform=newRegularByteTransform();#if!NETSTANDARD2_0serialPort=newSerialPort();#endif}#endregion#regionNetworkDataServerBaseOverride///<summary>///读取自定义的寄存器的值///</summary>///<paramname="address">起始地址,示例:"I100","M100"</param>///<paramname="length">数据长度</param>///<exceptioncref="IndexOutOfRangeException"></exception>///<returns>byte数组值</returns>publicoverrideOperateResult<byte[]>Read(stringaddress,ushortlength){OperateResult<string>analysis=XGBFastEnet.AnalysisAddress(address,true);if(!analysis.IsSuccess)returnOperateResult.CreateFailedResult<byte[]>(analysis);intstartIndex=CheckAddress(analysis.Content.Substring(3));switch(analysis.Content[1]){case'P':returnOperateResult.CreateSuccessResult(pBuffer.GetBytes(startIndex,length));case'Q':returnOperateResult.CreateSuccessResult(qBuffer.GetBytes(startIndex,length));case'M':returnOperateResult.CreateSuccessResult(SoftBasic.BoolArrayToByte(mBuffer.GetBool(startIndex,length*=8)));case'D':returnOperateResult.CreateSuccessResult(dBuffer.GetBytes(startIndex==0?startIndex:startIndex*=2,length));default:returnnewOperateResult<byte[]>(StringResources.Language.NotSupportedDataType);}}///<summary>///写入自定义的数据到数据内存中去///</summary>///<paramname="address">地址</param>///<paramname="value">数据值</param>///<returns>是否写入成功的结果对象</returns>publicoverrideOperateResultWrite(stringaddress,byte[]value){OperateResult<string>analysis=XGBFastEnet.AnalysisAddress(address,false);if(!analysis.IsSuccess)returnOperateResult.CreateFailedResult<byte[]>(analysis);intstartIndex=CheckAddress(analysis.Content.Substring(3));switch(analysis.Content[1]){case'P':pBuffer.SetBytes(value,startIndex);returnOperateResult.CreateSuccessResult();case'Q':qBuffer.SetBytes(value,startIndex);returnOperateResult.CreateSuccessResult();case'M':mBuffer.SetBool(value[0]==1?true:false,startIndex);returnOperateResult.CreateSuccessResult();case'D':dBuffer.SetBytes(value,startIndex==0?startIndex:startIndex*=2);returnOperateResult.CreateSuccessResult();default:returnnewOperateResult<byte[]>(StringResources.Language.NotSupportedDataType);}}#endregion#regionByteReadWriteOperate///<summary>///读取指定地址的字节数据///</summary>///<paramname="address">西门子的地址信息</param>///<returns>带有成功标志的结果对象</returns>publicOperateResult<byte>ReadByte(stringaddress){OperateResult<byte[]>read=Read(address,2);if(!read.IsSuccess)returnOperateResult.CreateFailedResult<byte>(read);returnOperateResult.CreateSuccessResult(read.Content[0]);}///<summary>///将byte数据信息写入到指定的地址当中///</summary>///<paramname="address">西门子的地址信息</param>///<paramname="value">字节数据信息</param>///<returns>是否成功的结果</returns>publicOperateResultWrite(stringaddress,bytevalue){returnWrite(address,newbyte[]{value});}#endregion#regionBoolReadWriteOperate///<summary>///读取指定地址的bool数据对象///</summary>///<paramname="address">西门子的地址信息</param>///<returns>带有成功标志的结果对象</returns>publicOperateResult<bool>ReadBool(stringaddress){OperateResult<string>analysis=XGBFastEnet.AnalysisAddress(address,true);if(!analysis.IsSuccess)returnOperateResult.CreateFailedResult<bool>(analysis);//todo,thisisnotrightintstartIndex=CheckAddress(analysis.Content.Substring(3));switch(analysis.Content[1]){case'P':returnOperateResult.CreateSuccessResult(pBuffer.GetBool(startIndex));case'Q':returnOperateResult.CreateSuccessResult(qBuffer.GetBool(startIndex));case'M':returnOperateResult.CreateSuccessResult(mBuffer.GetBool(startIndex));case'D':returnOperateResult.CreateSuccessResult(dBuffer.GetBool(startIndex));default:returnnewOperateResult<bool>(StringResources.Language.NotSupportedDataType);}}///<summary>///往指定的地址里写入bool数据对象///</summary>///<paramname="address">西门子的地址信息</param>///<paramname="value">值</param>///<returns>是否成功的结果</returns>publicOperateResultWrite(stringaddress,boolvalue){OperateResult<string>analysis=XGBFastEnet.AnalysisAddress(address,false);if(!analysis.IsSuccess)returnanalysis;//todo,thisisnotrightintstartIndex=CheckAddress(analysis.Content.Substring(3));switch(analysis.Content[1]){case'P':pBuffer.SetBool(value,startIndex);returnOperateResult.CreateSuccessResult();case'Q':qBuffer.SetBool(value,startIndex);returnOperateResult.CreateSuccessResult();case'M':mBuffer.SetBool(value,startIndex);returnOperateResult.CreateSuccessResult();case'D':dBuffer.SetBool(value,startIndex);returnOperateResult.CreateSuccessResult();default:returnnewOperateResult(StringResources.Language.NotSupportedDataType);}}#endregion#regionNetServerOverride///<summary>///当客户端登录后,进行Ip信息的过滤,然后触发本方法,也就是说之后的客户端需要///</summary>///<paramname="socket">网络套接字</param>///<paramname="endPoint">终端节点</param>protectedoverridevoidThreadPoolLoginAfterClientCheck(Socketsocket,System.Net.IPEndPointendPoint){//开始接收数据信息AppSessionappSession=newAppSession();appSession.IpEndPoint=endPoint;appSession.WorkSocket=socket;try{socket.BeginReceive(newbyte[0],0,0,SocketFlags.None,newAsyncCallback(SocketAsyncCallBack),appSession);AddClient(appSession);}catch{socket.Close();LogNet?.WriteDebug(ToString(),string.Format(StringResources.Language.ClientOfflineInfo,endPoint));}}privatevoidSocketAsyncCallBack(IAsyncResultar){if(ar.AsyncStateisAppSessionsession){try{intreceiveCount=session.WorkSocket.EndReceive(ar);LsisFastEnetMessagefastEnetMessage=newLsisFastEnetMessage();OperateResult<byte[]>read1=ReceiveByMessage(session.WorkSocket,5000,fastEnetMessage);if(!read1.IsSuccess){LogNet?.WriteDebug(ToString(),string.Format(StringResources.Language.ClientOfflineInfo,session.IpEndPoint));RemoveClient(session);return;};byte[]receive=read1.Content;byte[]SendData=null;if(receive[20]==0x54){//读数据SendData=ReadByMessage(receive);RaiseDataReceived(SendData);session.WorkSocket.Send(SendData);}elseif(receive[20]==0x58){SendData=WriteByMessage(receive);RaiseDataReceived(SendData);session.WorkSocket.Send(SendData);}else{session.WorkSocket.Close();}RaiseDataSend(receive);session.WorkSocket.BeginReceive(newbyte[0],0,0,SocketFlags.None,newAsyncCallback(SocketAsyncCallBack),session);}catch{//关闭连接,记录日志session.WorkSocket?.Close();LogNet?.WriteDebug(ToString(),string.Format(StringResources.Language.ClientOfflineInfo,session.IpEndPoint));RemoveClient(session);return;}}}privatebyte[]ReadByMessage(byte[]packCommand){List<byte>content=newList<byte>();content.AddRange(ReadByCommand(packCommand));returncontent.ToArray();}privatebyte[]ReadByCommand(byte[]command){varresult=newList<byte>();result.AddRange(SoftBasic.BytesArraySelectBegin(command,20));result[9]=0x11;result[10]=0x01;result[12]=0xA0;result[13]=0x11;result[18]=0x03;result.AddRange(newbyte[]{0x55,0x00,0x14,0x00,0x08,0x01,0x00,0x00,0x01,0x00});intNameLength=command[28];ushortRequestCount=BitConverter.ToUInt16(command,30+NameLength);stringDeviceAddress=Encoding.ASCII.GetString(command,31,NameLength-1);byte[]data=Read(DeviceAddress,RequestCount).Content;result.AddRange(BitConverter.GetBytes((ushort)data.Length));result.AddRange(data);result[16]=(byte)(result.Count-20);returnresult.ToArray();}privatebyte[]WriteByMessage(byte[]packCommand){varresult=newList<byte>();result.AddRange(SoftBasic.BytesArraySelectBegin(packCommand,20));result[9]=0x11;result[10]=0x01;result[12]=0xA0;result[13]=0x11;result[18]=0x03;result.AddRange(newbyte[]{0x59,0x00,0x14,0x00,0x08,0x01,0x00,0x00,0x01,0x00});intNameLength=packCommand[28];varDeviceAddress=Encoding.ASCII.GetString(packCommand,31,NameLength-1);intRequestCount=BitConverter.ToUInt16(packCommand,30+NameLength);byte[]data=ByteTransform.TransByte(packCommand,32+NameLength,RequestCount);Write(DeviceAddress,data);result[16]=(byte)(result.Count-20);returnresult.ToArray();}#endregion#regionDataSaveLoadOverride///<summary>///从字节数据加载数据信息///</summary>///<paramname="content">字节数据</param>protectedoverridevoidLoadFromBytes(byte[]content){if(content.Length<DataPoolLength*4)thrownewException("File is not correct");pBuffer.SetBytes(content,0,0,DataPoolLength);qBuffer.SetBytes(content,DataPoolLength,0,DataPoolLength);mBuffer.SetBytes(content,DataPoolLength*2,0,DataPoolLength);dBuffer.SetBytes(content,DataPoolLength*3,0,DataPoolLength);}///<summary>///将数据信息存储到字节数组去///</summary>///<returns>所有的内容</returns>protectedoverridebyte[]SaveToBytes(){byte[]buffer=newbyte[DataPoolLength*4];Array.Copy(pBuffer.GetBytes(),0,buffer,0,DataPoolLength);Array.Copy(qBuffer.GetBytes(),0,buffer,DataPoolLength,DataPoolLength);Array.Copy(mBuffer.GetBytes(),0,buffer,DataPoolLength*2,DataPoolLength);Array.Copy(dBuffer.GetBytes(),0,buffer,DataPoolLength*3,DataPoolLength);returnbuffer;}publicstaticintCheckAddress(stringaddress){intbitSelacdetAddress;switch(address){case"A":bitSelacdetAddress=10;break;case"B":bitSelacdetAddress=11;break;case"C":bitSelacdetAddress=12;break;case"D":bitSelacdetAddress=13;break;case"E":bitSelacdetAddress=14;break;case"F":bitSelacdetAddress=15;break;default:bitSelacdetAddress=int.Parse(address);break;}returnbitSelacdetAddress;}#endregion#regionPrivateMemberprivateSoftBufferpBuffer;//pdatatypeprivateSoftBufferqBuffer;//qdatatypeprivateSoftBuffermBuffer;//寄存器的数据池privateSoftBufferdBuffer;//输入寄存器的数据池privateconstintDataPoolLength=65536;//数据的长度#endregion#regionSerialSupportprivateintstation=1;#if!NETSTANDARD2_0privateSerialPortserialPort;//核心的串口对象///<summary>///使用默认的参数进行初始化串口,9600波特率,8位数据位,无奇偶校验,1位停止位///</summary>///<paramname="com">串口信息</param>publicvoidStartSerialPort(stringcom){StartSerialPort(com,9600);}///<summary>///使用默认的参数进行初始化串口,8位数据位,无奇偶校验,1位停止位///</summary>///<paramname="com">串口信息</param>///<paramname="baudRate">波特率</param>publicvoidStartSerialPort(stringcom,intbaudRate){StartSerialPort(sp=>{sp.PortName=com;sp.BaudRate=baudRate;sp.DataBits=8;sp.Parity=Parity.None;sp.StopBits=StopBits.One;});}///<summary>///使用自定义的初始化方法初始化串口的参数///</summary>///<paramname="inni">初始化信息的委托</param>publicvoidStartSerialPort(Action<SerialPort>inni){if(!serialPort.IsOpen){inni?.Invoke(serialPort);serialPort.ReadBufferSize=1024;serialPort.ReceivedBytesThreshold=1;serialPort.Open();serialPort.DataReceived+=SerialPort_DataReceived;}}///<summary>///关闭串口///</summary>publicvoidCloseSerialPort(){if(serialPort.IsOpen){serialPort.Close();}}///<summary>///接收到串口数据的时候触发///</summary>///<paramname="sender">串口对象</param>///<paramname="e">消息</param>privatevoidSerialPort_DataReceived(objectsender,SerialDataReceivedEventArgse){varsp=(SerialPort)sender;intrCount=0;byte[]buffer=newbyte[1024];byte[]receive=null;while(true){System.Threading.Thread.Sleep(20);intcount=sp.Read(buffer,rCount,sp.BytesToRead);rCount+=count;if(count==0)break;receive=newbyte[rCount];Array.Copy(buffer,0,receive,0,count);}if(receive==null)return;byte[]modbusCore=SoftBasic.BytesArrayRemoveLast(receive,2);byte[]SendData=null;if(modbusCore[3]==0x72){//ReadSendData=ReadSerialByCommand(modbusCore);RaiseDataReceived(SendData);serialPort.Write(SendData,0,SendData.Length);}elseif(modbusCore[3]==0x77){//WriteSendData=WriteSerialByMessage(modbusCore);RaiseDataReceived(SendData);serialPort.Write(SendData,0,SendData.Length);}else{serialPort.Close();}if(IsStarted)RaiseDataSend(receive);}publicbyte[]HexToBytes(stringhex){if(hex==null)thrownewArgumentNullException("The data is null");if(hex.Length%2!=0)thrownewFormatException("Hex Character Count Not Even");varbytes=newbyte[hex.Length/2];for(vari=0;i<bytes.Length;i++)bytes[i]=Convert.ToByte(hex.Substring(i*2,2),16);returnbytes;}privatebyte[]ReadSerialByCommand(byte[]command){varresult=newList<byte>();result.Add(0x06);//ENQresult.AddRange(SoftBasic.BuildAsciiBytesFrom((byte)station));result.Add(0x72);//commandrresult.Add(0x53);//commandtype:SBresult.Add(0x42);result.AddRange(Encoding.ASCII.GetBytes("01"));intNameLength=int.Parse(Encoding.ASCII.GetString(command,6,2));intRequestCount=Convert.ToInt32(Encoding.ASCII.GetString(command,8+NameLength,2),16);stringDeviceAddress=Encoding.ASCII.GetString(command,9,NameLength-1);byte[]data=Read(DeviceAddress,(ushort)RequestCount).Content;result.AddRange(SoftBasic.BuildAsciiBytesFrom((byte)data.Length));result.AddRange(SoftBasic.BytesToAsciiBytes(data));result.Add(0x03);//ETXintsum1=0;for(inti=0;i<result.Count;i++){sum1+=result[i];}result.AddRange(SoftBasic.BuildAsciiBytesFrom((byte)sum1));returnresult.ToArray();}privatebyte[]WriteSerialByMessage(byte[]packCommand){varresult=newList<byte>();stringNameLength,DeviceAddress;varRead=Encoding.ASCII.GetString(packCommand,3,3);result.Add(0x06);//ENQresult.AddRange(SoftBasic.BuildAsciiBytesFrom((byte)station));result.Add(0x77);//commandwresult.Add(0x53);//commandtype:SBresult.Add(0x42);result.Add(0x03);//EOTif(Read=="wSS"){NameLength=Encoding.ASCII.GetString(packCommand,8,2);DeviceAddress=Encoding.ASCII.GetString(packCommand,11,int.Parse(NameLength)-1);stringdata=Encoding.ASCII.GetString(packCommand,10+int.Parse(NameLength),2);Write(DeviceAddress,newbyte[]{(byte)(data=="01"?0x01:0x00)});}else{NameLength=Encoding.ASCII.GetString(packCommand,6,2);DeviceAddress=Encoding.ASCII.GetString(packCommand,9,int.Parse(NameLength)-1);intRequestCount=int.Parse(Encoding.ASCII.GetString(packCommand,8+int.Parse(NameLength),2));stringValue=Encoding.ASCII.GetString(packCommand,8+int.Parse(NameLength)+RequestCount,RequestCount*2);varwdArys=HexToBytes(Value);Write(DeviceAddress,wdArys);}returnresult.ToArray();}#endif#endregion#regionObjectOverride///<summary>///返回表示当前对象的字符串///</summary>///<returns>字符串信息</returns>publicoverridestringToString(){return$"LSisServer[{Port}]";}#endregion}}