无线监控系统之二-------C#实现
呵呵,虽然昨晚写得很辛苦了,但还是把我的第一部分写完了,呵呵~今晚就把第二部分写完吧,转载时请不要忘了注明本文来C/S框架网哦。
如图,我们先看看我们的解决方案,大体上按照MVC设计模型设计,分为用户视图层、业务逻辑层和数据访问层,另外还有公共处理模块和主窗体模块。 用户登录和主窗体就不多说了。。。。 一、我们首先来看看我们最核心的一层业务逻辑层LOGICDEAL。 (Ⅰ) COMMUNICATE包中主要是上位机与下位机数据通讯方式的实现。
通讯方式接口实现:
using System.Collections.Generic;
using System.Text;
namespace LOGICDEAL.COMMUNICATE
{
public interface CommunicateInter
{
void Open();
void Close();
void Read(int NumBytes);
byte[] getdata();
void Write(byte[] WriteBytes);
void setFtype(byte[] data);
}
}
串口通讯实现(serialport控件)
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.IO.Ports;
using System.IO;
using System.Threading;
namespace LOGICDEAL.COMMUNICATE
{
public class SerialCommu:CommunicateInter
{
private byte[] BufBytes = null;
//comm port win32 file handle
private SerialPort sport = null;
protected delegate void HandleInferfaceUpdateDelegate();
HandleInferfaceUpdateDelegate interfaceupdatedelegate = null;
public SerialCommu()
{
}
public void newCommu()
{
sport = new SerialPort();
}
//打开串口
public void Open()
{
//if (!sport.IsOpen) sport.Open();
if (sport == null)
{
newCommu();
sport.PortName = "com1"; //设置端口
sport.BaudRate = 57600;
sport.DataBits = 8;
sport.StopBits = System.IO.Ports.StopBits.One;
sport.Parity = System.IO.Ports.Parity.None;
//serialPort.RtsEnable = true;
//serialPort.Encoding = Encoding.UTF8;
sport.ReceivedBytesThreshold = 1;
interfaceupdatedelegate = new HandleInferfaceUpdateDelegate(resDataCodds); //委托,接收数据
this.sport.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.sport_DataReceived);
}
if (!sport.IsOpen)
{
try
{
sport.Open(); //打开端口
}
catch
{
return;
}
}
}
//关闭串口
public void Close()
{
if (sport.IsOpen) sport.Close();
}
//读取 NumBytes长度的字节
public void Read(int NumBytes)
{
if (!sport.IsOpen) Open(); //串口是否打开
int l = 0;
int l1 = 0;
int i=0;
byte[] bytes ;
BufBytes = new byte[NumBytes]; //需要读取的字节数
while(l<NumBytes) //读取数据
{
l1= sport.BytesToRead; //字节数
if (l1 == 0) continue;
bytes= new byte[l1];
sport.Read(bytes,0,l1);
for (i = 0; i < bytes.Length; i++) BufBytes[i + l] = bytes[i];
l +=bytes.Length; //已读取的字节数
}
setFtype(BufBytes);
}
public void Write(byte[] WriteBytes)
{
if (!sport.IsOpen) Open();
sport.Write(WriteBytes,0,WriteBytes.Length); //写串口
}
public void sport_DataReceived(object sender, SerialDataReceivedEventArgs e) //数据监听,接收
{
try
{
interfaceupdatedelegate.Invoke(); //唤醒
// Read(22);
}
catch { }
}
public void resDataCodds() { Read(22); } //读取数据
public byte[] getdata() //获取数据,供外部类
{
return BufBytes;
}
public void setFtype(byte[] data)
{
if (data[4].ToString("x").Trim().Equals("2")) LOGICDEAL.COMMUNICATE.Cflag.setFtype(0); //获取温度值
if (data[4].ToString("x").Trim().Equals("3")) LOGICDEAL.COMMUNICATE.Cflag.setFtype(1); //更新网络地址
}
}
}
fFlag单例实现
{
public class Cflag
{
private static CommunicateInter CType = null; //通讯类型
private static bool OFlag = true; // 通讯口是否已打开
private static int FType = -1; //数据帧功能类型
public static void setCtpye(CommunicateInter ci) { CType = ci; } //设置通讯类型
public static CommunicateInter getCtype() { return CType; } //获取通讯类型
public static void setOflag(bool oflag) { OFlag = oflag; } //设置打开类型,true为打开
public static bool getOfag() { return OFlag; } //获取打开类型
public static void setFtype(int i) { FType = i; } //设置数据帧功能类型,0:温度数值,1:
public static int getFtype() { return FType; }
}
(Ⅱ) DATAFRAME包中主要实现数据帧及其处理接口
数据帧接口
using System.Collections.Generic;
using System.Text;
namespace LOGICDEAL.DATAFRAME
{
public interface DataFrameInter
{
byte[] dealFrame(byte[] frame); //接收数据帧函数
byte[] sendFrame(); //发送数据帧函数
void setAFI();
}
}
数据帧处理接口
{
interface ArthFrameInter
{
byte[] dealData(byte[] framdata); //数据帧处理函数
}
}
数据帧接口实现一:温度值数据帧类TemValueData
{
class TemValueData:DataFrameInter
{
private ArthFrameInter afi = null; //工厂模式:对应的数据帧处理类
private int n=22, m=9;
public TemValueData()
{
}
public byte[] dealFrame(byte[] frame) //接收数据帧函数,温度值数据帧长度为21字节
{
if (afi.dealData(frame) == null) return null;
byte[] adata = new byte[m]; //需要输出的字节数组,长度为9字节
Array.Copy(afi.dealData(frame), adata, m);
//adata = afi.dealData(frame);
return adata;
}
public byte[] sendFrame() //发送数据帧函数
{
byte[] a = new byte[10];
return a;
}
public void setAFI() //获取数据帧处理类实例
{
this.afi = new TemValueArth();
}
}
}
{
public class TemValueArth:ArthFrameInter
{
private int n = 22, m = 9;
public byte[] dealData(byte[] framdata) //数据帧处理函数
{
if (!framdata[0].ToString("x").Trim().Equals("aa")) return null;
if (!framdata[2].ToString("x").Trim().Equals("11")) return null;
if ((!framdata[4].ToString("x").Trim().Equals("3")) && (!framdata[4].ToString("x").Trim().Equals("2"))) return null;
int textds = 0;
for (int j = 0; j < n - 2; j++) //计算前20字节数之和
{
textds += Convert.ToInt32(COMMONDEAL.DataConversion.Hex2Ten(framdata[j].ToString("x").Trim()));
}
int efficy = Convert.ToInt32(COMMONDEAL.DataConversion.Hex2Ten(framdata[n - 2].ToString("x").Trim() + framdata[n - 1].ToString("x").Trim())); //计算效验码值
if (textds != efficy) { return null; }
byte[] adata = new byte[m];
adata[0] = framdata[5]; //提取数据,2字节
adata[1] = framdata[6];
adata[2] = framdata[13]; //提取源地址,2字节
adata[3] = framdata[14];
adata[4] = framdata[15]; //提取网络地址,2字节
adata[5] = framdata[16];
adata[6] = framdata[17]; //网络号,1字节
adata[7] = framdata[18]; //提取通道,1字节
adata[8] = framdata[19]; //提取RSSI,1字节
return adata;
}
}
}
(Ⅲ) DEALTHREAD包中用户窗体与数据逻辑层的数据处理线程类:
用户窗体与数据逻辑层的数据处理线程类DealThread
{
public abstract class DealThread
{
//SynchronizationContext
private COMMUNICATE.CommunicateInter cci = null; //通讯类型
private DATAFRAME. DataFrameInter dfi = null; //数据帧
public Thread thread = null; //线程
public byte[] data=null; //处理后的数据
public abstract void init(); //初始化 //数据处理
public void start() { thread.Start(); } //开始线程
public abstract void run(); //线程运行函数
public void stop() { thread.Abort();} //停止线程
public byte[] getData() //获得最终数据
{
return data;
}
}
}
接口实现一:温度值处理线程类TemVlueThd
{
public class TemVlueThd:DealThread
{
private COMMUNICATE.CommunicateInter cci = null; //通讯类型
private DATAFRAME.DataFrameInter dfi = null; //数据帧
//private Thread thread = null; //线程
byte[] dataa = null;
private int n = 22, m = 9;
public TemVlueThd() //构造函数
{
init();
}
public override void init()
{
this.cci = COMMUNICATE.Cflag.getCtype(); //初始化通讯类
this.dfi = new DATAFRAME.TemValueData(); //初始化数据帧类
dfi.setAFI();
this.thread = new Thread(new ThreadStart(this.run)); //申请线程
//throw new Exception("The method or operation is not implemented.");
}
public override void run() //线程运行的方法
{
dataa = new byte[n];
if (cci.getdata() == null) return;
Array.Copy(cci.getdata(), dataa, n);
if (dfi.dealFrame(dataa) == null) return;
data = new byte[m]; //返回的数据
Array.Copy(dfi.dealFrame(dataa), data, m);
}
}
}
呵呵~~这一帖第二部分先写到这了。。。。谢谢大家!