/// <summary> /// 方法重载 /// </summary> /// <param name="example"></param> /// <param name="data"></param> /// <param name="msgid">用以实现自定义模式的包编号</param> /// <returns></returns> public static byte AddRequire(Compare example, object data, int msgid) { //根据destID获取目标主机的IP和port,这里如果发送多个数据需多次跟数据库通信 //麻烦,所以可以一次性将ip和port读到数据字典 IPEndPoint endpointtemp = Define.id_ip_port[example.destID]; PacketRet pr = Packetization(example, data, msgid); //加入发送队列 Define.SendQueueItem sqi = new Define.SendQueueItem(); sqi.destpoint = endpointtemp; sqi.senddata = pr.packetdata; Define.send_queue.Enqueue(sqi); //如果是一帧中的第一包 //计时队列和摘要队列是一次添加,内容不变化 //这里存在安全隐患:关联于队列中暂留项目的冲突可能性 if (!Define.index_obj.ContainsKey(pr.packetnum)) { //加入计时队列 TimerTick.count初始为30 Define.existime.Add(pr.packetnum, TimerTick.count); //加入发送缓存队列 Define.index_obj.Add(pr.packetnum, data); //加入到摘要队列 Define.index_com.Add(pr.packetnum, example); } //针对一帧多包,一帧中的后续包 else { //更新发送缓冲队列 Define.index_obj[pr.packetnum] = data; } return(pr.packetnum); }
/// <summary> /// 将发送的数据帧添加到发送缓冲队列 /// </summary> /// <param name="example"></param> /// <param name="data"></param> /// <param name="donewrite">仅针对于文件的写,且是分多次写下的情况</param> public static byte AddRequire(Compare example, object data) { //根据destID获取目标主机的IP和port,这里如果发送多个数据需多次跟数据库通信 //麻烦,所以可以一次性将ip和port读到数据字典 IPEndPoint endpointtemp = new IPEndPoint(IPAddress.Parse(MyDictionary.ID_IP[example.destID]), MyDictionary.ID_PORT[example.destID]); PacketRet pr = Packetization(example, data); //加入发送队列 Define.SendQueueItem sqi = new Define.SendQueueItem(); sqi.destpoint = endpointtemp; sqi.senddata = pr.packetdata; Define.send_queue.Enqueue(sqi); //如果是一帧中的第一包 //计时队列和摘要队列是一次添加,内容不变化 if (!Define.index_obj.ContainsKey(pr.packetnum)) { //加入计时队列 TimerTick.count初始为30 Define.existime.Add(pr.packetnum, TimerTick.count); //加入发送缓存队列 Define.index_obj.Add(pr.packetnum, data); //加入到摘要队列 Define.index_com.Add(pr.packetnum, example); } //针对一帧多包,一帧中的后续包 else { //更新发送缓冲队列 Define.index_obj[pr.packetnum] = data; } return(pr.packetnum); }
/// <summary> /// 如果是多包数据,那么分包后放到list中 /// 1、当需要组包时,传入参数,分析、使用switch区分,组装不同的帧 /// 2、类型和子类型的方法分别用于区分和组装数据域外数据 /// 3、针对不同的功能组织不同的数据域,最后合并 /// 4、ref donewrite参数为写文件准备,返回本次组包本地读取的字节数 /// </summary> /// <param name="destid"></param> /// <param name="msgtype"></param> /// <param name="msgsubtype"></param> /// <returns>错误代码另外给出</returns> public static PacketRet Packetization(Compare example, object data) { byte[] frame = null; PacketRet tempret = new PacketRet(); //packetization的错误代码定义另外给出 tempret.errorcode = 0; switch (example.msgType) { //读操作单元 case (byte)MSGEncoding.MsgType.ReadUnit: { switch (example.msgSubType) { //读数据 case (byte)MSGEncoding.ReadUint.ReadData: { frame = ReadUnit.ReadData(example.destID, (ushort[])data); break; } //读取配置信息 case (byte)MSGEncoding.ReadUint.Readcfg: { frame = ReadUnit.Readcfg(example.destID, (ushort[])data); break; } //查询设备状态 case (byte)MSGEncoding.ReadUint.GetDevStatus: { frame = ReadUnit.GetDevStatus(example.destID, (ushort[])data); break; } default: { //MessageBox.Show("preparedata-packetzation:错误子代码!"); tempret.errorcode = 1; } break; } break; } //写操作单元 case (byte)MSGEncoding.MsgType.WriteUnit: { //为适应前台,测试其他成功后添加转换 Dictionary <ushort, object> data_temp = WriteUnit.TransDict(((Dictionary <string, object>)data)); switch (example.msgSubType) { //控制设备(应该是状态/控制量) case (byte)MSGEncoding.WriteUint.ControlDev: { frame = WriteUnit.ControlDev(example.destID, data_temp); break; } //设置配置信息(配置量) case (byte)MSGEncoding.WriteUint.Setcfg: { frame = WriteUnit.Setcfg(example.destID, data_temp); break; } //写数据(数据量) case (byte)MSGEncoding.WriteUint.WriteData: { frame = WriteUnit.WriteData(example.destID, data_temp); break; } default: { //MessageBox.Show("preparedata-packetzation:错误子代码!"); tempret.errorcode = 1; } break; } break; } //读文件 case (byte)MSGEncoding.MsgType.ReadFile: { switch (example.msgSubType) { //读取指定配置文件,从x位置开始的n个字节数据 case (byte)MSGEncoding.ReadFile.ReadcfgFile: { frame = ReadFile.ReadcfgFile(example.destID, (ReadFile.Parameter)data); break; } //读取指定数据文件,从x位置开始的n个字节数据 case (byte)MSGEncoding.ReadFile.ReadDataFile: { frame = ReadFile.ReadDataFile(example.destID, (ReadFile.Parameter)data); break; } default: { //MessageBox.Show("preparedata-packetzation:错误子代码!"); tempret.errorcode = 1; } break; } break; } //写文件到设备 //注意:传入的para中的filehandle已经初始化 case (byte)MSGEncoding.MsgType.WriteFile: { switch (example.msgSubType) { //上传配置文件到设备,并作为最新配置 case (byte)MSGEncoding.WriteFile.UpcfgToDev: { frame = WriteFile.UpcfgToDev(example.destID, (WriteFile.Parameter)data); break; } //上传数据文件到设备 case (byte)MSGEncoding.WriteFile.UpDataToDev: { frame = WriteFile.UpDataToDev(example.destID, (WriteFile.Parameter)data); break; } //上传升级文件 case (byte)MSGEncoding.WriteFile.UpGradeFile: { frame = WriteFile.UpGradeFile(example.destID, (WriteFile.Parameter)data); break; } default: { //MessageBox.Show("preparedata-packetzation:错误子代码!"); tempret.errorcode = 1; } break; } break; } //通信测试 case (byte)MSGEncoding.MsgType.LoopBack: { //LoopBack通讯测试用 frame = LoopBack.LoopTest(example.destID, (ushort)data); break; } //其他(向设备查询Error Code的详细解释) case (byte)MSGEncoding.MsgType.GetErrorInfo: { //向设备查询Error Code的详细解释 frame = GetErrorInfo.ExplainError(example.destID, (ushort)data); break; } //文件信息查询 case (byte)MSGEncoding.MsgType.GetFileInfo: { switch (example.msgSubType) { //取得配置文件名称(=最新更新时间)及文件大小 case (byte)MSGEncoding.GetFileInfo.GetcfgFile: { frame = GetFileInfo.GetcfgFile(example.destID, (GetFileInfo.Parameter)data); break; } //按日期范围查询数据文件名及文件大小 case (byte)MSGEncoding.GetFileInfo.GetFileByRange: { frame = GetFileInfo.GetFileByRange(example.destID, (GetFileInfo.Parameter)data); break; } //查询离指定日期最近的x个数据文件名及文件大小 case (byte)MSGEncoding.GetFileInfo.GetXFileByLately: { frame = GetFileInfo.GetXFileByLately(example.destID, (GetFileInfo.Parameter)data); break; } default: { //MessageBox.Show("preparedata-packetzation:错误子代码!"); tempret.errorcode = 1; } break; } break; } //读缓冲区 case (byte)MSGEncoding.MsgType.ReadBuffer: { switch (example.msgSubType) { //读CO2气体的采样缓存 case (byte)MSGEncoding.ReadBuffer.ReadCO2Cache: { frame = ReadBuffer.ReadCO2Cache(example.destID, (ReadBuffer.Parameter)data); break; } //读六种气体的采样缓存 case (byte)MSGEncoding.ReadBuffer.ReadGasCache: { frame = ReadBuffer.ReadGasCache(example.destID, (ReadBuffer.Parameter)data); break; } //读H2O采样数据缓存 case (byte)MSGEncoding.ReadBuffer.ReadH2OCache: { frame = ReadBuffer.ReadH2OCache(example.destID, (ReadBuffer.Parameter)data); break; } default: { //MessageBox.Show("preparedata-packetzation:错误子代码!"); tempret.errorcode = 1; } break; } break; } default: { //MessageBox.Show("preparedata-packetzation:数据帧外层类型存在错误!"); tempret.errorcode = 2; } break; } try { //为统一发送和接受帧的对照,添加的标志,这里稳定后挪进所有帧组装方法中 byte[] changeframe = new byte[frame.Length + 1]; Array.Copy(frame, 0, changeframe, 0, 8); changeframe[8] = packetindex; Array.Copy(frame, 8, changeframe, 9, frame.Length - 8); tempret.packetnum = packetindex; tempret.packetdata = frame; //通过自动溢出归零 packetindex++; } catch (Exception ep) { //组好的原始帧中插入帧编码存在错误! //MessageBox.Show("preparedata-packetization:"+ep.ToString()); tempret.errorcode = 3; } return(tempret); }