• C#设备处理类操作


    C#设备处理类操作

    C#对于处理window操作系统下的设备有天然的优势,对于大多数设备读写等操作来说基本上够了,这里只讨论通过普通的大多数的设备的操作。涉及到两大类SerialPort类,Socket的一些操作。不一定好,但希望分享出去,让更多的人受益。。

    由于设备的读写方式不同,串口,网口,usb,等各种各样不同的方式,所以对外的操作,可能就达不到统一,没法集中处理,造成很大程度代码冗余,会给维护带来很大不便。需要一个父类来对不同操作进行统一的一个约束,同时可以对外有一个统一的j接口,方便业务上边的一些处理。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace EquipmentOption
    {
    public abstract class Equipment
    {

    /// <summary>
    /// 读取到的Code
    /// </summary>
    public string Code;
    /// <summary>
    /// 错误消息
    /// </summary>
    public string Error = string.Empty;
    public BaseEquipment EquipmentModel;

    public int ReadTimeOut=500;
    public Equipment(BaseEquipment Model)
    {
    this.EquipmentModel = Model;
    }
    /// <summary>
    /// 扫描事件
    /// </summary>
    private int scanning;
    public int Scanning
    {
    get
    {
    return this.scanning;
    }
    set
    {
    this.scanning = value;
    EquipmentArgs e = new EquipmentArgs(this.Code, this.Error);
    OnSetVelues(e);
    }
    }
    public event SetEventHandler SetEvent;
    public delegate void SetEventHandler(object sender, EquipmentArgs e);
    public class EquipmentArgs : EventArgs
    {
    public string Code;
    public string Error;
    public EquipmentArgs(string SnCode,string error)
    {
    this.Code = SnCode;
    this.Error = error;
    }
    }
    public void OnSetVelues(EquipmentArgs e)
    {
    if (this.SetEvent != null)
    {
    this.SetEvent(this, e);
    }
    }
    /// <summary>
    /// 检测设备
    /// </summary>
    /// <param name="message">错误消息返回值,仅当返回false才有值</param>
    /// <returns></returns>
    public abstract bool test(out string message);
    /// <summary>
    /// 给设备发送指令
    /// </summary>
    /// <param name="command">指令内容</param>
    /// <param name="type">指令类型</param>
    /// <returns></returns>
    public abstract string SendMessage(String command, CommandType type);
    }

    }

    复制代码
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace EquipmentOption
     7 {
     8     public abstract class Equipment
     9     {
    10 
    11         /// <summary>
    12         /// 读取到的Code
    13         /// </summary>
    14         public string Code;
    15         /// <summary>
    16         /// 错误消息
    17         /// </summary>
    18         public string Error = string.Empty;
    19         public BaseEquipment EquipmentModel;
    20 
    21         public int ReadTimeOut=500;
    22         public Equipment(BaseEquipment Model)
    23         {
    24             this.EquipmentModel = Model;
    25         }
    26         /// <summary>
    27         /// 扫描事件
    28         /// </summary>
    29         private int scanning;
    30         public int Scanning
    31         {
    32             get
    33             {
    34                 return this.scanning;
    35             }
    36             set
    37             {
    38                 this.scanning = value;
    39                 EquipmentArgs e = new EquipmentArgs(this.Code, this.Error);
    40                 OnSetVelues(e);
    41             }
    42         }
    43         public event SetEventHandler SetEvent;
    44         public delegate void SetEventHandler(object sender, EquipmentArgs e);
    45         public class EquipmentArgs : EventArgs
    46         {
    47             public string Code;
    48             public string Error;
    49             public EquipmentArgs(string SnCode,string error)
    50             {
    51                 this.Code = SnCode;
    52                 this.Error = error;
    53             }
    54         }
    55         public void OnSetVelues(EquipmentArgs e)
    56         {
    57             if (this.SetEvent != null)
    58             {
    59                 this.SetEvent(this, e);
    60             }
    61         }
    62         /// <summary>
    63         /// 检测设备
    64         /// </summary>
    65         /// <param name="message">错误消息返回值,仅当返回false才有值</param>
    66         /// <returns></returns>
    67         public abstract bool test(out string message);
    68         /// <summary>
    69         /// 给设备发送指令
    70         /// </summary>
    71         /// <param name="command">指令内容</param>
    72         /// <param name="type">指令类型</param>
    73         /// <returns></returns>
    74         public abstract string SendMessage(String command, CommandType type);
    75     }
    76     
    77 }
    复制代码

    父类里边主要定义了一些公用的属性,以及一个简单的事件转发。这个事件转发用于统一网口设备和串口设备的获取数据方式

    调用方式如下:

    复制代码
            private void Form1_Load(object sender, EventArgs e)
            {
                Equipment Comquip = new ComEquipment(new BaseEquipment());
                Comquip.SetEvent += Equipment_GetCodeEvent;
                Equipment IPEquip = new IPEquipment(new BaseEquipment());
                IPEquip.SetEvent += Equipment_GetCodeEvent;
            }
            void Equipment_GetCodeEvent(object sender, Equipment.EquipmentArgs e)
            {
                string code = e.Code;//这里的Code就是从设备中读取到的值
            }
    复制代码

     可以把需要用到的基础消息丢到baseEquipment中用来初始化对应的设备,然后,把对于设备读取到的信息就是这里的e.code。不管网口串口都是一样的返回. 

    设备的操作无非读写

    对于用串口连接的设备:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO.Ports;
    using System.Threading;
    namespace EquipmentOption
    {
    public class ComEquipment : Equipment
    {
    private SerialPort Port;
    public ComEquipment(BaseEquipment baseModel) :
    base(baseModel)
    {
    this.Port = new SerialPort(baseModel.Port);
    Port.BaudRate = baseModel.BaudRate;
    Port.StopBits = (StopBits)baseModel.StopBit;
    Port.Parity = (Parity)baseModel.ParityCheck;
    this.Port.DataReceived += Port_DataReceived;
    }
    //事件转发
    void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
    Thread.Sleep(this.EquipmentModel.SleepTime);
    this.Error = string.Empty;
    this.Code = string.Empty;
    try
    {
    switch (this.EquipmentModel.ReadType)
    {
    case 1:
    this.Code = (sender as SerialPort).ReadLine();
    break;
    case 2:
    this.Code = (sender as SerialPort).ReadExisting();
    break;
    default:
    Error = string.Concat(this.EquipmentModel.EquipmentName, "读取有误");
    break;
    }
    ++this.Scanning;//这里切记是属性值变化才会触发事件

    }
    catch
    {
    Error = string.Concat(this.EquipmentModel.EquipmentName, "配置错误,请调整");
    }
    }

    /// <summary>
    /// 检测
    /// </summary>
    /// <param name="message"></param>
    /// <returns></returns>
    public override bool test(out string message)
    {
    message = "";
    bool result = false;
    if (this.Port != null)
    {
    try
    {
    Port.Open();
    result = true;
    }
    catch
    {
    message = string.Concat("设备", this.EquipmentModel.EquipmentName, "异常");
    result = false;
    }
    finally
    {
    if (Port.IsOpen)
    {
    Port.Close();
    }
    }
    }
    else
    {
    message = string.Concat("设备", this.EquipmentModel.EquipmentName, "初始化失败");
    result = false;
    }
    return result;
    }
    /// <summary>
    /// 发送命令
    /// </summary>
    /// <param name="command">命令</param>
    public override string SendMessage(String command, CommandType type)
    {
    if (!String.IsNullOrEmpty(command) && this.Port.IsOpen)
    {
    switch (type)
    {
    case CommandType.GetBytes:
    Byte[] commandsGetBytes = CommandConvert.CommandByGetBytes(command);
    this.Port.Write(commandsGetBytes, 0, commandsGetBytes.Length);
    break;
    case CommandType.Command16:
    Byte[] commands16 = CommandConvert.CommandFrom16(command);
    this.Port.Write(commands16, 0, commands16.Length);
    break;
    case CommandType.Command10:
    Byte[] commands10 = CommandConvert.CommandFrom10(command);
    this.Port.Write(commands10, 0, commands10.Length);
    break;
    case CommandType.CommandText:
    this.Port.Write(command);
    break;
    }
    return this.Port.PortName + "发送数据:" + command;
    }
    else
    {
    return "串口" + this.Port.PortName + "未打开";
    }
    }
    }
    }

    复制代码
      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.IO.Ports;
      6 using System.Threading;
      7 namespace EquipmentOption
      8 {
      9     public class ComEquipment : Equipment
     10     {
     11         private SerialPort Port;
     12         public ComEquipment(BaseEquipment baseModel) :
     13             base(baseModel)
     14         {
     15             this.Port = new SerialPort(baseModel.Port);
     16             Port.BaudRate = baseModel.BaudRate;
     17             Port.StopBits = (StopBits)baseModel.StopBit;
     18             Port.Parity = (Parity)baseModel.ParityCheck;
     19             this.Port.DataReceived += Port_DataReceived;
     20         }
     21         //事件转发
     22         void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
     23         {
     24             Thread.Sleep(this.EquipmentModel.SleepTime);
     25             this.Error = string.Empty;
     26             this.Code = string.Empty;
     27             try
     28             {
     29                 switch (this.EquipmentModel.ReadType)
     30                 {
     31                     case 1:
     32                         this.Code = (sender as SerialPort).ReadLine();
     33                         break;
     34                     case 2:
     35                         this.Code = (sender as SerialPort).ReadExisting();
     36                         break;
     37                     default:
     38                         Error = string.Concat(this.EquipmentModel.EquipmentName, "读取有误");
     39                         break;
     40                 }
     41                 ++this.Scanning;//这里切记是属性值变化才会触发事件
     42 
     43             }
     44             catch
     45             {
     46                 Error = string.Concat(this.EquipmentModel.EquipmentName, "配置错误,请调整");
     47             }
     48         }
     49 
     50         /// <summary>
     51         /// 检测
     52         /// </summary>
     53         /// <param name="message"></param>
     54         /// <returns></returns>
     55         public override bool test(out string message)
     56         {
     57             message = "";
     58             bool result = false;
     59             if (this.Port != null)
     60             {
     61                 try
     62                 {
     63                     Port.Open();
     64                     result = true;
     65                 }
     66                 catch
     67                 {
     68                     message = string.Concat("设备", this.EquipmentModel.EquipmentName, "异常");
     69                     result = false;
     70                 }
     71                 finally
     72                 {
     73                     if (Port.IsOpen)
     74                     {
     75                         Port.Close();
     76                     }
     77                 }
     78             }
     79             else
     80             {
     81                 message = string.Concat("设备", this.EquipmentModel.EquipmentName, "初始化失败");
     82                 result = false;
     83             }
     84             return result;
     85         }
     86         /// <summary>
     87         /// 发送命令
     88         /// </summary>
     89         /// <param name="command">命令</param>
     90         public override string SendMessage(String command, CommandType type)
     91         {
     92             if (!String.IsNullOrEmpty(command) && this.Port.IsOpen)
     93             {
     94                 switch (type)
     95                 {
     96                     case CommandType.GetBytes:
     97                         Byte[] commandsGetBytes = CommandConvert.CommandByGetBytes(command);
     98                         this.Port.Write(commandsGetBytes, 0, commandsGetBytes.Length);
     99                         break;
    100                     case CommandType.Command16:
    101                         Byte[] commands16 = CommandConvert.CommandFrom16(command);
    102                         this.Port.Write(commands16, 0, commands16.Length);
    103                         break;
    104                     case CommandType.Command10:
    105                         Byte[] commands10 = CommandConvert.CommandFrom10(command);
    106                         this.Port.Write(commands10, 0, commands10.Length);
    107                         break;
    108                     case CommandType.CommandText:
    109                         this.Port.Write(command);
    110                         break;
    111                 }
    112                 return this.Port.PortName + "发送数据:" + command;
    113             }
    114             else
    115             {
    116                 return "串口" + this.Port.PortName + "未打开";
    117             }
    118         }
    119     }
    120 }
    复制代码

    对于用网口连接的设备:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;

    namespace EquipmentOption
    {
    public class IPEquipment : Equipment
    {
    private IPEndPoint IPPort;
    private IPAddress IP;
    public IPEquipment(BaseEquipment baseModel) :
    base(baseModel)
    {
    int Port = 0;
    if (int.TryParse(baseModel.Port, out Port))
    {
    this.IP = IPAddress.Parse(baseModel.IPAddress);
    this.IPPort = new IPEndPoint(IP, Port);
    Thread t = new Thread(new ParameterizedThreadStart(ScanEvent));
    t.Start(IPPort);
    }
    }

    public override bool test(out string message)
    {
    bool result = false; message = "";
    Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 创建Socket
    try
    {
    c.SendTimeout = 5000;
    c.Connect(IPPort); //连接到服务器
    result = true;
    }
    catch
    {
    message =string.Concat("设备" , this.EquipmentModel.EquipmentName , "异常");
    result = false;
    }
    finally
    {
    c.Close();
    }
    return result;
    }
    public void ScanEvent(object ipe)
    {
    while (true)
    {
    try
    {
    //创建Socket并连接到服务器
    Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 创建Socket
    c.Connect((IPEndPoint)ipe); //连接到服务器
    //接受从服务器返回的信息
    byte[] recvBytes = new byte[1024];
    int bytes;
    //bytes = c.Receive(recvBytes, recvBytes.Length, 0); //从服务器端接受返回信息
    bytes = c.Receive(recvBytes);
    string Code = Encoding.Default.GetString(recvBytes, 0, bytes);
    Code = Code.Replace(EquipmentModel.Suffix, "");
    this.Code = Code;
    c.Close();
    ++this.Scanning;
    }
    catch(Exception ex)
    {
    Error = ex.ToString();
    continue;
    }
    }
    }

    public override string SendMessage(string command, CommandType type)
    {
    //new mothed to SendMessage;
    return "";
    }
    }
    }

    复制代码
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Net;
     6 using System.Net.Sockets;
     7 using System.Threading;
     8 
     9 namespace EquipmentOption
    10 {
    11     public class IPEquipment : Equipment
    12     {
    13         private IPEndPoint IPPort;
    14         private IPAddress IP;
    15         public IPEquipment(BaseEquipment baseModel) :
    16             base(baseModel)
    17         {
    18             int Port = 0;
    19             if (int.TryParse(baseModel.Port, out Port))
    20             {
    21                 this.IP = IPAddress.Parse(baseModel.IPAddress);
    22                 this.IPPort = new IPEndPoint(IP, Port);
    23                 Thread t = new Thread(new ParameterizedThreadStart(ScanEvent));
    24                 t.Start(IPPort);
    25             }
    26         }
    27 
    28         public override bool test(out string message)
    29         {
    30             bool result = false; message = "";
    31             Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   //  创建Socket
    32             try
    33             {
    34                 c.SendTimeout = 5000;
    35                 c.Connect(IPPort); //连接到服务器
    36                 result = true;
    37             }
    38             catch
    39             {
    40                 message =string.Concat("设备" , this.EquipmentModel.EquipmentName , "异常");
    41                 result = false;
    42             }
    43             finally
    44             {
    45                 c.Close();
    46             }
    47             return result;
    48         }
    49         public void ScanEvent(object ipe)
    50         {
    51             while (true)
    52             {
    53                 try
    54                 {
    55                     //创建Socket并连接到服务器
    56                     Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   //  创建Socket
    57                     c.Connect((IPEndPoint)ipe); //连接到服务器
    58                     //接受从服务器返回的信息
    59                     byte[] recvBytes = new byte[1024];
    60                     int bytes;
    61                     //bytes = c.Receive(recvBytes, recvBytes.Length, 0);    //从服务器端接受返回信息
    62                     bytes = c.Receive(recvBytes);
    63                     string Code = Encoding.Default.GetString(recvBytes, 0, bytes);
    64                     Code = Code.Replace(EquipmentModel.Suffix, "");
    65                     this.Code = Code;
    66                     c.Close();
    67                     ++this.Scanning;
    68                 }
    69                 catch(Exception ex)
    70                 {
    71                     Error = ex.ToString();
    72                     continue;
    73                 }
    74             }
    75         }
    76 
    77         public override string SendMessage(string command, CommandType type)
    78         {
    79             //new mothed to SendMessage;
    80             return "";
    81         }
    82     }
    83 }
    复制代码

    对于扩展而言,需要做的仅仅是不同类别的设备再增加不同的子类去继承抽象类.

  • 相关阅读:
    往鼠标位置写入 诗词
    shell条件判断
    shell 案例一
    Shell中的变量
    echo e 命令详解
    Docker 安装RedisJSON 与使用
    Python 插入数据库的各种方式
    Python压缩文件/文件夹
    shell运算符
    关于CAN总线简单总结
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5319950.html
Copyright © 2020-2023  润新知