.net下的面向工控领域的远程方法调用(RMI)中间件,客户端协议栈应答端实现

远程方法调用,在服务器端执行完毕后,其反馈结果也必然是,按照字节流的方式返回,服务器端按照通信协议,做封包处理,而客户端的应答处理部分,从通信连接会话上,接收到待解析的字节流数据,负责解析,转化成客户端可执行的结构体数据。

解包过程时,需要从外到内逐级向下,上级解包状态决定了下级解包时,调用的消息处理器。


下面是同步调用过程的客户端协议拆包过程:

1      通信协议包格式

用于对客户端和服务器端通信时,数据传输过程中的数据包的封装处理,只负责具体的数据

包传输,此为整个封包的最外层包装。

起始标记位

包体长度

加密标记

数据包内容

4Byte

Int32

1Byte

字节流

用于标记数据包的开始,

0x02,0x03,0xFF,0xFF

用于标记数据包的长度,LittleEndian

0x00,不加密

0x01,加密

所有数据的内容,需要下面的“数据包内容协议格式定义”进一步处理

 

拆包代码,此处拆包代码引入了底层的通信组件,Trace.Common.Communication.dll,在其他文章处有介绍,

 /// <summary>
    /// RMI应答消息解析器
    /// </summary>
    public class RMIClientDataOutputFilter : Trace.Common.Communication.Message.BaseOutPutMessageFilter<RMIClientDataRequest, RMIClientDataResponse>
    {
        private IMessageFilterHelper messageFilterHelper = null;
        /// <summary>
        /// 包头
        /// </summary>
        private byte[] start = new byte[] { 0x02, 0x03, 0xFF, 0xFF };
        /// <summary>
        /// 应答处理上下文
        /// </summary>
        private List<RMIResponseContext> responseContextList = new List<RMIResponseContext>();
        /// <summary>
        /// 应答上下文处理锁
        /// </summary>
        private object responseContextLock = new object();
        public RMIClientDataOutputFilter()
        {
            messageFilterHelper = new MessageFilterFixStartLengthHelper(start, 4, 60000);
        }
        /// <summary>
        /// 将通信流压入待处理的解析器
        /// </summary>
        /// <param name="sessionID">会话ID</param>
        /// <param name="buffer"></param>
        protected override void InputBufferData(string sessionID, byte[] buffer)
        {
            messageFilterHelper.InputBufferData(buffer);
        }
        /// <summary>
        /// 拆包
        /// </summary>
        /// <returns></returns>
        protected override RMIClientDataResponse GetNextResponse()
        {
            byte[] tempBuffer = messageFilterHelper.GetNextData();
            if (tempBuffer == null || tempBuffer.Length == 0)
            {
                return null;
            }
            RMIClientDataResponse response = new RMIClientDataResponse();
            try
            {
                response = this.Response(tempBuffer, response);
            }
            catch (Exception ex)
            {
                response.Exception = ex;
            }
            return response;
        }
        /// <summary>
        /// 应答解析处理
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="response"></param>
        /// <returns></returns>
        private RMIClientDataResponse Response(byte[] buffer, RMIClientDataResponse response)
        {
            PackDataOutputFilter packDataOutputFilter = new PackDataOutputFilter();
            packDataOutputFilter.SetBuffer(buffer);
            if (packDataOutputFilter.RMIDataBlockFlag == RMIDataBlockFlag.AllBlock)//整包传输
            {
                this.AllBlockDataPro(packDataOutputFilter);
            }
            else if (packDataOutputFilter.RMIDataBlockFlag == RMIDataBlockFlag.AllBlockACK
                || packDataOutputFilter.RMIDataBlockFlag == RMIDataBlockFlag.AllBlockNAK)//整包传输成功\失败确认
            {
                this.AllBlockConfirm(packDataOutputFilter);
            }

            else if (packDataOutputFilter.RMIDataBlockFlag == RMIDataBlockFlag.SplitBlock)//分包传输
            {

            }
            else if (packDataOutputFilter.RMIDataBlockFlag == RMIDataBlockFlag.SplitBlockACK
                || packDataOutputFilter.RMIDataBlockFlag == RMIDataBlockFlag.SplitBlockNAK)//分包传输成功、失败确认
            {

            }
            return response;
        }
        /// <summary>
        /// 整包数据确认
        /// </summary>
        /// <param name="packDataOutputFilter"></param>
        private void AllBlockConfirm(PackDataOutputFilter packDataOutputFilter)
        {
            AllBlockConfirmOutputFilter allBlockConfirmOutputFilter = new AllBlockConfirmOutputFilter();
            allBlockConfirmOutputFilter.SetBuffer(packDataOutputFilter.LeftBuffer);
            if (packDataOutputFilter.RMIDataBlockFlag == RMIDataBlockFlag.AllBlockNAK)//整包传输失败确认
            { 
            
            }
        }
        /// <summary>
        /// 整包数据处理
        /// </summary>
        /// <param name="packDataOutputFilter"></param>
        private void AllBlockDataPro(PackDataOutputFilter packDataOutputFilter)
        {
            AllBlockDataOutputFilter allBlockDataOutputFilter = new AllBlockDataOutputFilter();
            allBlockDataOutputFilter.SetBuffer(packDataOutputFilter.LeftBuffer);
            if (allBlockDataOutputFilter.RMIVersion == RMIVersion.Version1)//版本1处理器
            {
                this.ExcuteContentVersion1(allBlockDataOutputFilter.LeftBuffer);
            }
        }
        /// <summary>
        /// 版本1,执行体数据处理
        /// </summary>
        /// <param name="excuteBuffer">执行体数据</param>
        private RMIResponseContext ExcuteContentVersion1(byte[] excuteBuffer)
        {
            RMIResponseContext context;
            ResponseDataOutputFilterVersion1 responseDataOutputFilterVersion1 = new ResponseDataOutputFilterVersion1();
            responseDataOutputFilterVersion1.SetBuffer(excuteBuffer);
            if (responseDataOutputFilterVersion1.RMIResponseType == RMIResponseType.SyncRequestResponse)//同步应答
            {
                context = new RMISyncResponseContext();
                context.RequestObjCallID = responseDataOutputFilterVersion1.RequestObjCallID;
                context.RequestMethodID = responseDataOutputFilterVersion1.RequestMethodID;
                SyncResponseOutputFilterVersion1 syncResponseOutputFilterVersion1 = new SyncResponseOutputFilterVersion1();
                syncResponseOutputFilterVersion1.SetBuffer(responseDataOutputFilterVersion1.LeftBuffer);
                context.ResponseStatus = syncResponseOutputFilterVersion1.ResponseStatus;
                if (syncResponseOutputFilterVersion1.ResponseStatus == RMIResponseStatus.IsResult)//同步应答返回结果
                {
                    SyncResponseOutputFilterVersion1IsResult syncResponseOutputFilterVersion1IsResult = new SyncResponseOutputFilterVersion1IsResult(responseDataOutputFilterVersion1.SerializeType);
                    syncResponseOutputFilterVersion1IsResult.SetBuffer(syncResponseOutputFilterVersion1.LeftBuffer);
                }
                else if (syncResponseOutputFilterVersion1.ResponseStatus == RMIResponseStatus.IsNull)//空的返回
                {
                    SyncResponseOutputFilterVersion1IsNull syncResponseOutputFilterVersion1IsNull = new SyncResponseOutputFilterVersion1IsNull();
                    syncResponseOutputFilterVersion1IsNull.SetBuffer(syncResponseOutputFilterVersion1.LeftBuffer);
                }
                else if (syncResponseOutputFilterVersion1.ResponseStatus == RMIResponseStatus.Exception)//异常返回
                {
                    SyncResponseOutputFilterVersion1IsException syncResponseOutputFilterVersion1IsException = new SyncResponseOutputFilterVersion1IsException(responseDataOutputFilterVersion1.SerializeType);
                    syncResponseOutputFilterVersion1IsException.SetBuffer(syncResponseOutputFilterVersion1.LeftBuffer);
                }
            }
            else if (responseDataOutputFilterVersion1.RMIResponseType == RMIResponseType.ASyncRequestResponse)//异步应答
            {
                

1.1    数据包内容协议格式定义:

包唯一ID

包标记

数据块内容

数据包校验位

GUI(16Byte)

1Byte

字节流

1Byte

当前传输数据包的唯一ID

0x00,表示整包传输,

0x01,表示分包传输

0x02,表示整包传输确认

0x03,表示分包传输确认

0x04,表示整包传输失败

0x05,表示分包传输失败

需要下面进一步处理

校验和,对数据包内容中的所有数据,进行校验和

 

1.1.1    整包传输数据块协议

版本号

命令状态

执行体

Int32

Byte

字节流

用于标记处理数据的版本

0x00,请求命令

0x01,应答命令

需要到“执行体协议”进一步处理

 

 

此处按照整包数据块,协议解析代码,

  /// <summary>
    /// 包体数据解析
    /// </summary>
    public class PackDataOutputFilter : IRMISplitResponseOutputFilter
    {
        private Guid packID;
        /// <summary>
        /// 数据包唯一ID
        /// </summary>
        public Guid PackID
        {
            get 
            {
                return packID;
            }
        }
        private RMIDataBlockFlag rMIDataBlockFlag;
        /// <summary>
        /// 包标记
        /// </summary>
        public RMIDataBlockFlag RMIDataBlockFlag
        {
            get 
            {
                return this.rMIDataBlockFlag;
            }
        }
        private byte[] leftBuffer;
        /// <summary>
        /// 剩余数据
        /// </summary>
        public byte[] LeftBuffer
        {
            get 
            {
                return this.leftBuffer;
            }
        }
       /// <summary>
       /// 包体数据解析
       /// </summary>
       /// <param name="buffer"></param>
        public void SetBuffer(byte[] buffer)
        {
            this.CheckSum(buffer);
            Trace.Common.Communication.MessageStatck.MessageStatckSplit messageStatckSplit = new Trace.Common.Communication.MessageStatck.MessageStatckSplit(buffer);
            Guid tempPackID;
            if (messageStatckSplit.PopGUID(out tempPackID) == false)
            {
                throw new Exception("获取数据包唯一ID失败");
            }
            this.packID = tempPackID;
            byte bRMIDataBlockFlag;
            if (messageStatckSplit.PopByte(out bRMIDataBlockFlag) == false)
            {
                throw new Exception("获取包标记失败");
            }
            this.rMIDataBlockFlag = (RMIDataBlockFlag)bRMIDataBlockFlag;
            this.leftBuffer = messageStatckSplit.GetLeftDataBuffer();
        }
        /// <summary>
        /// 进行校验和处理
        /// </summary>
        /// <param name="dataBuffer">体数据</param>
        /// <returns></returns>
        public void CheckSum(byte[] dataBuffer)
        {
            int len = dataBuffer.Length;
            byte tempCheck = dataBuffer[len - 1];
            byte checkSum = 0x00;
            for (int i = 0; i < len-1; i++)
            {
                checkSum += dataBuffer[i];
            }
            if (tempCheck != checkSum)
            {
                throw new Exception("数据包校验失败");
            }
        }
    }


 /// <summary>
    /// 整数据块解析处理
    /// </summary>
    public class AllBlockDataOutputFilter : IRMISplitResponseOutputFilter
    {
        private RMIVersion rmiVersion;
        /// <summary>
        /// 版本号
        /// </summary>
        public RMIVersion RMIVersion
        {
            get 
            {
                return rmiVersion;
            }
        }
        private RMICommand rmiCommand;
        /// <summary>
        /// 命令状态
        /// </summary>
        public RMICommand RMICommand
        {
            get 
            {
                return rmiCommand;
            }
        }
        private byte[] leftBuffer;
        /// <summary>
        /// 剩余数据
        /// </summary>
        public byte[] LeftBuffer
        {
            get
            {
                return this.leftBuffer;
            }
        }
        /// <summary>
        /// 数据解析处理
        /// </summary>
        /// <param name="buffer"></param>
        public void SetBuffer(byte[] buffer)
        {
            Trace.Common.Communication.MessageStatck.MessageStatckSplit messageStatckSplit = new Trace.Common.Communication.MessageStatck.MessageStatckSplit(buffer);
            Int32 versionCode;
            if (messageStatckSplit.PopInt32(out versionCode) == false)
            {
                throw new Exception("获取版本代码失败");
            }
            this.rmiVersion = (RMIVersion)versionCode;
            byte bCommand;
            if (messageStatckSplit.PopByte(out bCommand) == false)
            {
                throw new Exception("获取命令状态失败");
            }
            this.rmiCommand = (RMICommand)bCommand;
            this.leftBuffer = messageStatckSplit.GetLeftDataBuffer();
        }
    }

1      服务端版本1,执行体协议

1.1    函数反馈应答

启用的序列化协议

客户端请求对象ID

客户端调用过程ID

应答方式

具体的应答处理

1Byte

GUID(16Byte)

GUID(16Byte)

1Byte

字节流

0x00,Json序列化,

0x01,ProtoBuf序列化

用于标记客户端发起请求的对象

用于标记客户端发起请求的调用函数

用于标记服务器端的应答方式,

0x01, 同步请求应答

0x02,订阅回调

0x03,异步请求应答

 

 

 

 


到执行体部分了,拆包协议处理,

/// <summary>
    /// 执行体数据消息解析器
    /// </summary>
    public class ResponseDataOutputFilterVersion1:IRMISplitResponseOutputFilter
    {
        private RMISerializeType serializeType;
        /// <summary>
        /// 序列化方式
        /// </summary>
        public RMISerializeType SerializeType
        {
            get 
            {
                return serializeType;
            }
        }

        private Guid requestObjCallID;
        /// <summary>
        /// 原始请求对象ID
        /// </summary>
        public Guid RequestObjCallID
        {
            get 
            {
                return requestObjCallID;
            }
        }

        private Guid requestMethodID;
        /// <summary>
        /// 原始请求方法ID
        /// </summary>
        public Guid RequestMethodID
        {
            get 
            {
                return this.requestMethodID;
            }
        }

        private RMIResponseType responseType;
        /// <summary>
        /// 应答方式
        /// </summary>
        public RMIResponseType RMIResponseType
        {
            get 
            {
                return responseType;
            }
        }

        private byte[] leftBuffer;
        /// <summary>
        /// 剩余字节数量
        /// </summary>
        public byte[] LeftBuffer
        {
            get 
            {
                return leftBuffer;
            }
        }
        /// <summary>
        /// 执行体协议应答解析处理
        /// </summary>
        /// <param name="buffer">执行体数据包</param>
        public void SetBuffer(byte[] buffer)
        {
            Trace.Common.Communication.MessageStatck.MessageStatckSplit messageStatckSplit = new Trace.Common.Communication.MessageStatck.MessageStatckSplit(buffer);
            byte bSerializeType;
            if (messageStatckSplit.PopByte(out bSerializeType) == false)
            {
                throw new Exception("获取启用的序列化协议失败");
            }
            this.serializeType = (RMISerializeType)bSerializeType;
            Guid tempObjID;
            if (messageStatckSplit.PopGUID(out tempObjID) == false)
            {
                throw new Exception("获取请求对象ID失败");
            }
            this.requestObjCallID = tempObjID;
            Guid tempMethodID;
            if (messageStatckSplit.PopGUID(out tempMethodID) == false)
            {
                throw new Exception("获取调用过程ID失败");
            }
            this.requestMethodID = tempMethodID;
            byte bResponseType;
            if (messageStatckSplit.PopByte(out bResponseType) == false)
            {
                throw new Exception("获取应答方式失败");
            }
            this.responseType = (RMIResponseType)bResponseType;
            this.leftBuffer = messageStatckSplit.GetLeftDataBuffer();
        }
    }


1.1.1    客户端同步请求应答

应答状态

返回数据

1Byte

字节流

用于标记应答的信息流状态

0x00 空的返回

0x01 存在数据

0x02 异常信息

 

 /// <summary>
    /// 同步应答解析处理器
    /// </summary>
    public class SyncResponseOutputFilterVersion1 : IRMISplitResponseOutputFilter
    {
        private RMIResponseStatus responseStatus=RMIResponseStatus.UnKnow;
        /// <summary>
        /// 应答状态
        /// </summary>
        public RMIResponseStatus ResponseStatus
        {
            get 
            {
                return responseStatus;
            }
        }
        private byte[] leftBuffer;
        /// <summary>
        /// 剩余字节数量
        /// </summary>
        public byte[] LeftBuffer
        {
            get 
            {
                return leftBuffer;
            }
        }
         /// <summary>
        /// 执行体协议应答解析处理
        /// </summary>
        /// <param name="buffer">执行体数据包</param>
        public void SetBuffer(byte[] buffer)
        {
            Trace.Common.Communication.MessageStatck.MessageStatckSplit messageStatckSplit = new Trace.Common.Communication.MessageStatck.MessageStatckSplit(buffer);
            byte bResponseStatus;
            if (messageStatckSplit.PopByte(out bResponseStatus) == false)
            {
                throw new Exception("获取应答状态失败");
            }
            this.responseStatus = (RMIResponseStatus)bResponseStatus;
            this.leftBuffer = messageStatckSplit.GetLeftDataBuffer();
        }
    }

1.1.1.1             存在数据

返回类型全名字节流长度

返回类型全名字节流

返回序列化内容字节流长度

返回序列化内容字节流

Int32

字节流

Int32

字节流

用于标记返回类型全名字节流长度

用于描述返回类型全名对应的字符串,UTF8编码后的字节流

用于标记返回序列化内容字节流长度

将返回内容进行序列化后,并经UTF8编码后的字节流

 /// <summary>
    /// 同步应答解析,反馈数据
    /// </summary>
    public class SyncResponseOutputFilterVersion1IsResult : IRMISplitResponseOutputFilter
    {
        private RMISerializeType serializeType;
        /// <summary>
        /// 序列化方式
        /// </summary>
        /// <param name="serializeType"></param>
        public SyncResponseOutputFilterVersion1IsResult(RMISerializeType serializeType)
        {
            this.serializeType = serializeType;
        }
        private object data;
        /// <summary>
        /// 反馈回的应答数据
        /// </summary>
        public object Data
        {
            get 
            {
                return data;
            }
        }
        /// <summary>
        /// 正常数据解析处理
        /// </summary>
        /// <param name="buffer">执行体数据包</param>
        public void SetBuffer(byte[] buffer)
        {
            Trace.Common.Communication.MessageStatck.MessageStatckSplit messageStatckSplit = new Trace.Common.Communication.MessageStatck.MessageStatckSplit(buffer);
            IRMISerializble serialize = null;
            if (serializeType == RMISerializeType.Json)
            {
                serialize = new RMIJsonSerialize();
            }
            int readPaTypeLen = 0;
            if (messageStatckSplit.PopInt32(out readPaTypeLen) == false)
            {
                throw new Exception("返回类型长度获取失败");
            }
            string paTypeName;
            if (messageStatckSplit.PopUTF8String(out paTypeName, readPaTypeLen) == false)
            {
                throw new Exception("返回类型获取失败");
            }
            Type paType = Type.GetType(paTypeName);
            int contentLength = 0;
            if (messageStatckSplit.PopInt32(out contentLength) == false)
            {
                throw new Exception("返回内容长度获取失败");
            }
            if (contentLength > 0)
            {
                byte[] paBuffer = messageStatckSplit.PopBytes(contentLength);
                this.data = serialize.DeSerializeByUTF8(paType, paBuffer);
            }
        }
    }



深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值