⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gprscomm.cs

📁 GPRS数据采集驱动源码
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Threading;
using System.Collections;

namespace GPRSDrvWinApp.gprs
{

	#region 基础数据结构

	//Gprs实时数据结构
	public struct GprsData
	{
		public uint m_DeviceID;			//设备号		
		public uint m_ChannelCount;		//通道数
		public uint[] m_ChannelData;	//通道数据集
	}

	
	#endregion

	#region GprsComm公共类 

	/// <summary>
	/// GprsComm 的摘要说明。
	/// </summary>
	public class GprsComm
	{
		#region 成员变量
		private GprsData gprsData;

		private string errorMsg = "";		

		private uint validCount = 0;	//有效包计数器
		private uint invalidCount = 0;	//无效包计数器
		private uint totalCount = 0;	//总接收包计数器

		//RTU物理通道配置信息
		public Hashtable htRtuPackage;

		//Socket:从GPRS接收实时数据
		public Socket SocketRecvFromGprs = null;
		public EndPoint EndPointRecvFromGprs = null;

		//Socket:发送实时数据到中控
		public Socket SocketSendToCenter = null;
		public EndPoint EndPointSendToCenter = null;

		public string DebugFileName;	
		public uint ExceptionCount = 0;
		public StreamWriter swDebugFile = null;

		public System.Windows.Forms.StatusBar sbStatistic;
		public System.Windows.Forms.ListBox lbData;


		#region GPRS通讯包协议定义

		//数据包的长度
		public const uint GPRS_DATAPACK_WIDTH=512;
			
		// GPRS包标志符位置和长度
		public const uint GPRS_PACKID_INDEX = 0;
		public const uint GPRS_PACKID_WIDTH = 4;

		//GPRS的IP地址
		public const uint GPRS_IP_INDEX = 4;
		public const uint GPRS_IP_WIDTH = 4;

		// GPRS包中设备号的位置和长度
		public const uint GPRS_DEVICEID_INDEX=8;
		public const uint GPRS_DEVICEID_WIDTH=4;

		//包的数据类型
		public const uint GPRS_DATA_RECV_TYPE_INDEX = 12;

		//通道数据的起始位置
		public const uint GPRS_CHANNEL_DATA_INDEX=13;
	

		#endregion
		

		#region 驱动程序 → 中控程序 通讯包协议定义

		//包头代码168
		public const byte CENTER_HEAD_IDENTIFIER = 0xA8;  // 168

		//包头索引号、字节数
		public const uint CENTER_HEAD_INDEX = 0;
		public const uint CENTER_HEAD_WIDTH = 1;

		//包类型索引号、字节数
		public const uint CENTER_TYPE_INDEX = 1;
		public const uint CENTER_TYPE_WIDTH = 1;

		//包总长度索引号、字节数
		public const uint CENTER_LEN_INDEX = 2;
		public const uint CENTER_LEN_WIDTH = 4;

		//设备号索引号、字节数
		public const uint CENTER_DEVICEID_INDEX = 6;
		public const uint CENTER_DEVICEID_WIDTH = 4;

		//包尾字节数、包尾代码169
		public const uint CENTER_END_WIDTH = 1;		
		public const byte CENTER_END_IDENTIFIER = 0xA9;  // 169

		#endregion
		
		#region 驱动程序 → 中控程序 中控实时数据包特有格式

		//1:实时数据表类型为
		public const byte CENTER_SEND_NORMALDATA_TYPE = 0x01;
			
		// 包含通道个数
		public const uint CENTER_SEND_NORMALDATA_NUM_INDEX = 10;
		public const uint CENTER_SEND_NORMALDATA_NUM_WIDTH = 1;

		// 实时数据开始
		public const uint CENTER_SEND_NORMALDATA_INDEX = 11;				

		// 通道数据组织
		public const uint CENTER_SEND_NORMALDATA_CHANNELKEY_WIDTH = 1;
		public const uint CENTER_SEND_NORMALDATA_CHANNELVALUE_WIDTH = 4;
		public const uint CENTER_SEND_NORMALDATA_CHANNELTOTAL_WIDTH = 5;
		
		#endregion

		#endregion
		
		public delegate void showInfo_sub_delegate(string strInfo);	
		public delegate void showStatistic_sub_delegate(uint nTotal, uint nValid, uint nInvalid);


		#region 构造函数
		public GprsComm()
		{
			//TODO: 在此处添加构造函数逻辑
		}

		public GprsComm(DriverConfig driverCfg,String DebugFileName,ListBox lbData,StatusBar sbStatistic, Hashtable htRtuPackage)
		{
			gprsData = new GprsData();

			//Socket:从GPRS接收实时数据
			SocketRecvFromGprs = CreateBindedSocket(driverCfg.IpRecvFromGprs, driverCfg.PortRecvFromGprs.ToString());
			EndPointRecvFromGprs = (EndPoint) new IPEndPoint(IPAddress.Any, 0);
			
			//Socket:发送实时数据到中控
			SocketSendToCenter = CreateBindedSocket(IPAddress.Any.ToString(), "0");
			EndPointSendToCenter = (EndPoint) new IPEndPoint(IPAddress.Parse(driverCfg.IpSendToCenter), driverCfg.PortSendToCenter);				

			this.DebugFileName=DebugFileName;
			this.lbData=lbData;
			this.sbStatistic=sbStatistic;

			//RTU物理通道配置信息
			this.htRtuPackage = htRtuPackage;
		}
		
		#endregion	
		


		/// <summary>
		/// 组中控的数据包
		/// </summary>
		/// <param name="kind">1:实时数据包 2:历史数据包 3:校时数据包</param>
		/// <param name="nDeviceID">设备号</param>
		/// <param name="bytesRecv">原始包</param>
		/// <returns></returns>
		private  byte[] CreateCenterPackage(string kind, uint nDeviceID, byte[] bytesRecv)
		{
			byte[] SendToCenterBytes;
			uint nSendBytesLength = 0;
			byte[] FourBytesBuffer=new byte[4];
			
			SendToCenterBytes=new byte[GPRS_DATAPACK_WIDTH];
			
			switch(kind)
			{
					#region 实时数据
				case "1":					

					if(SetNormalData(ref gprsData, nDeviceID, bytesRecv))
					{						
						// 计算中控实时数据包的总长度,包含包头定义、通道数据和包尾
						nSendBytesLength = CENTER_HEAD_WIDTH + 
							CENTER_TYPE_WIDTH + 
							CENTER_LEN_WIDTH + 
							CENTER_DEVICEID_WIDTH + 
							CENTER_SEND_NORMALDATA_NUM_WIDTH + 
							Convert.ToUInt16(gprsData.m_ChannelCount) * CENTER_SEND_NORMALDATA_CHANNELTOTAL_WIDTH +
							CENTER_END_WIDTH;

						SendToCenterBytes = new byte[nSendBytesLength];

						SendToCenterBytes[CENTER_HEAD_INDEX] = CENTER_HEAD_IDENTIFIER;										
						SendToCenterBytes[CENTER_TYPE_INDEX] = CENTER_SEND_NORMALDATA_TYPE;										
						bool bBytesNumberFlag = MyTypeTranslator.UintToFourBytes(nSendBytesLength,ref FourBytesBuffer);
						if(bBytesNumberFlag)
						{
							//设置长度
							for(int i=0; i<CENTER_LEN_WIDTH; i++)
							{
								SendToCenterBytes[CENTER_LEN_INDEX+i] = FourBytesBuffer[i];												
							}

							//设置实时包的设备号
							bool bDeviceIDFlag=MyTypeTranslator.UintToFourBytes(gprsData.m_DeviceID,ref FourBytesBuffer);//
							if(bDeviceIDFlag)
							{
								for(int i=0; i<CENTER_DEVICEID_WIDTH; i++)
								{
									SendToCenterBytes[CENTER_DEVICEID_INDEX+i]=FourBytesBuffer[i];													
								}

								SendToCenterBytes[CENTER_SEND_NORMALDATA_NUM_INDEX] = Convert.ToByte(gprsData.m_ChannelCount);
											
								for (int i = 0; i < gprsData.m_ChannelCount; i++)
								{
									SendToCenterBytes[CENTER_SEND_NORMALDATA_INDEX + i * 5] = Convert.ToByte(i + 1);//通道号是从1开始计算,故加1
									bool bRTUChannelDataFlag=MyTypeTranslator.UintToFourBytes(gprsData.m_ChannelData[i],ref FourBytesBuffer);
									if(bRTUChannelDataFlag)
									{
										for(int j=0; j < CENTER_SEND_NORMALDATA_CHANNELVALUE_WIDTH; j++)
										{
											SendToCenterBytes[CENTER_SEND_NORMALDATA_INDEX + i * 5 + j + 1]=FourBytesBuffer[j];
										}
									}													
								}
								SendToCenterBytes[SendToCenterBytes.Length - 1] = CENTER_END_IDENTIFIER;
							}
						}
					}
					break;
					#endregion					
				case "2":
					#region 历史数据

					break;
					#endregion
				case "3":
					#region 终端时钟					

					#endregion
					break;
				default:
					break;
			}
			return SendToCenterBytes;
		}

		#region 实时数据
		/// <summary>
		/// 设置实时数据
		/// </summary>
		/// <param name="gprsData"></param>
		/// <param name="pString"></param>
		/// <returns></returns>
		private  bool SetNormalData(ref GprsData gprsData, uint nDeviceID, byte[] bytesRecv)
		{
			try
			{
				gprsData.m_DeviceID = nDeviceID;


				//判断RTU通道配置信息里是否包含此rtu设备
				if (htRtuPackage.Contains(nDeviceID))
				{
					RtuPackage rtuPackage = (RtuPackage) htRtuPackage[nDeviceID];
					//有效通道个数
					gprsData.m_ChannelCount = (uint)rtuPackage.m_ValidChannelIndex.Length;

					//填充通道数据
					gprsData.m_ChannelData=FillChannel(rtuPackage, bytesRecv);

				}
				else
				{
					return false;			
				}			

				
			}
			catch
			{
				return false;
			}
			return true;
		}
		
		#endregion


		#region 填充RTU通道数据

		/// <summary>
		/// 填充通道
		/// </summary>
		/// <param name="strdata"></param>
		/// <param name="channelcount"></param>
		/// <returns></returns>
		private  uint[]  FillChannel(RtuPackage rtuPackage, byte[] bytesRecv)
		{
			//有效通道个数
			int channelCount = rtuPackage.m_ValidChannelIndex.Length;
			uint[] arrChannelData = new uint[channelCount];

			byte[] TwoBytesArray = new byte[2];
			byte[] ThreeBytesArray = new byte[3];
			byte[] FourBytesArray = new byte[4];

			uint ChannelIndexBuf=GPRS_CHANNEL_DATA_INDEX;
			uint ChannelValue=0;

			//循环提取有效通道数据
			for( int k=0; k<channelCount; k++)
			{
				bool bFlag = false;

				switch(rtuPackage.m_ValidChannelWidth[k])
				{
					case 1:
						ChannelValue = (uint)bytesRecv[ChannelIndexBuf + rtuPackage.m_ValidChannelIndex[k]];
						arrChannelData[k] = ChannelValue;						
						ChannelValue=0;
						break;
					case 2:
						for(int i=0;i<TwoBytesArray.Length;i++)
						{
							TwoBytesArray[i] = bytesRecv[ChannelIndexBuf + rtuPackage.m_ValidChannelIndex[k] + i];
						}

						bFlag=MyTypeTranslator.TwoBytesToUint(TwoBytesArray,ref ChannelValue);
						if(bFlag)
							arrChannelData[k] = ChannelValue;						
						ChannelValue=0;
						break;
					case 3:
						for(int i=0;i<ThreeBytesArray.Length;i++)
						{
							ThreeBytesArray[i] = bytesRecv[ChannelIndexBuf + rtuPackage.m_ValidChannelIndex[k] + i];
						}
						bFlag=MyTypeTranslator.ThreeBytesToUint(ThreeBytesArray,ref ChannelValue);
						if(bFlag)
							arrChannelData[k] = ChannelValue;						
						ChannelValue=0;
						break;
					case 4:
						for(int i=0;i<FourBytesArray.Length;i++)
						{
							FourBytesArray[i] = bytesRecv[ChannelIndexBuf + rtuPackage.m_ValidChannelIndex[k] + i];
						}
						bFlag=MyTypeTranslator.FourBytesToUint(FourBytesArray,ref ChannelValue);
						if(bFlag)
							arrChannelData[k] = ChannelValue;						
						ChannelValue=0;
						break;
					default:break;
				}				

			}

			return arrChannelData;

		}

		#endregion

		

		
		


		/// <summary>
		/// 返回一个已绑定的SOCKET对象
		/// </summary>
		/// <param name="ip">IP地址</param>
		/// <param name="port">绑定的端口</param>
		/// <returns></returns>
		private Socket CreateBindedSocket(string ip,string  port)
		{

			IPEndPoint ipepoint=new IPEndPoint(IPAddress.Parse(ip.Trim()),int.Parse(port.Trim()));
			Socket socket=new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

			socket.Bind(ipepoint);
			return socket;
		}

		#endregion


		#region 公有方法
		/// <summary>
		/// 线程:接收来自GPRS设备的实时数据,并重新组包发送到中控
		/// </summary>
		public void StartRecvGPRSSendCenter()
		{
			Socket SocketRecvFromGprsBuffer = SocketRecvFromGprs;
			EndPoint EndPointRecvFromGprsBuffer = EndPointRecvFromGprs;

			Socket SocketSendToCenterBuffer = SocketSendToCenter;
			EndPoint EndPointSendToCenterBuffer = EndPointSendToCenter;

			System.Windows.Forms.ListBox listBox1Buffer = lbData;
			System.Windows.Forms.StatusBar statusBar1Buffer = sbStatistic;

		
			String DebugFileNameBuffer=DebugFileName;
			uint ExceptionCountBuffer=ExceptionCount;
			StreamWriter swDebugFileBuffer=null;

			uint GPRS_DATAPACK_WIDTH_BUFFER=GPRS_DATAPACK_WIDTH;	//包长度 512
			uint GPRS_DEVICEID_INDEX_BUFFER=GPRS_DEVICEID_INDEX;	//设备号位置
			uint GPRS_DEVICEID_WIDTH_BUFFER=GPRS_DEVICEID_WIDTH;	//设备号长度
			int GPRS_CHANNEL_DATA_INDEX_BUFFER=(int)GPRS_CHANNEL_DATA_INDEX;	//通道数据位置		
//			uint GPRS_DATA_RECV_TYPE_INDEX_BUFFER=GPRS_DATA_RECV_TYPE_INDEX;	//数据包类型

			byte[] bytesRecv = new byte[GPRS_DATAPACK_WIDTH_BUFFER];
			byte[] bytesSendToCenter=new byte[GPRS_DATAPACK_WIDTH_BUFFER];
			

			int nRecvCount=0;
			
			string strInfo = "";
			string Recvpackage="";

			while(true)
			{
				try
				{
					for(int i=0; i<bytesRecv.Length; i++)
						bytesRecv[i]=0;

					// 接收来自GPRS的数据,没有数据则阻塞。
					nRecvCount=SocketRecvFromGprsBuffer.ReceiveFrom(bytesRecv, ref EndPointRecvFromGprsBuffer);

					Recvpackage=Encoding.ASCII.GetString(bytesRecv);					

					//保存数据包成文本文件
//					WriteToTxt(swDebugFileBuffer,Recvpackage);

					byte DatapackID=bytesRecv[GPRS_DATA_RECV_TYPE_INDEX];

				
					if(listBox1Buffer.Items.Count==100)
					{
						listBox1Buffer.Items.Clear();
					}

					// 计算接收到的数据包个数
					totalCount++;
					if(totalCount==UInt32.MaxValue)
					{
						totalCount=0;
						invalidCount=0;
						validCount=0;
					}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -