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 }
复制代码

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

原文地址:https://www.cnblogs.com/Leo_wl/p/5319950.html