C#设备处理类操作

2020-08-31 15:13:00 浏览数 (1)

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

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

代码语言:javascript复制
 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 }

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

调用方式如下:

代码语言:javascript复制
        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。不管网口串口都是一样的返回.

设备的操作无非读写

对于用串口连接的设备:

代码语言:javascript复制
  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 }

对于用网口连接的设备:

代码语言:javascript复制
 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 }

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

0 人点赞