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=;
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);
} }

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

调用方式如下:

        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 :
this.Code = (sender as SerialPort).ReadLine();
break;
case :
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, , commandsGetBytes.Length);
break;
case CommandType.Command16:
Byte[] commands16 = CommandConvert.CommandFrom16(command);
this.Port.Write(commands16, , commands16.Length);
break;
case CommandType.Command10:
Byte[] commands10 = CommandConvert.CommandFrom10(command);
this.Port.Write(commands10, , commands10.Length);
break;
case CommandType.CommandText:
this.Port.Write(command);
break;
}
return this.Port.PortName + "发送数据:" + command;
}
else
{
return "串口" + this.Port.PortName + "未打开";
}
}
}
}

对于用网口连接的设备:

 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 = ;
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 = ;
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[];
int bytes;
//bytes = c.Receive(recvBytes, recvBytes.Length, 0); //从服务器端接受返回信息
bytes = c.Receive(recvBytes);
string Code = Encoding.Default.GetString(recvBytes, , 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 "";
}
}
}

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

C#设备处理类操作的更多相关文章

  1. 在Android下通过ExifInterface类操作图片的Exif信息

    什么是Exif 先来了解什么是Exif.Exif是一种图像文件格式,它的数据存储于JPEG格式是完全相同的,实际上Exif格式就是JPEG格式头插入了 数码照片的信息,包括拍摄的光圈.快门.平衡白.I ...

  2. HTML5 01. 布局、语义化标签、智能化表单、表单元素/标签/属性/事件、多媒体、类操作、自定义属性

    1.知识点 lang = “en”   所用语言是英文 文档结构更简洁 IE8一下不支持h5c3 书写更宽松 div没有语义 标签语义化:在合适的地方使用合适的标签 对seo优化友谊 网页经典布局 页 ...

  3. 谢欣伦 - OpenDev原创教程 - 设备查找类CxDeviceFind & CxDeviceMapFind

    这是一个精练的设备查找类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxDeviceFind的使用如下: void CUsbSc ...

  4. Arrays 类操作 Java 的数组排序

    使用 Arrays 类操作 Java 中的数组 Arrays 类是 Java 中提供的一个工具类,在 java.util 包中.该类中包含了一些方法用来直接操作数组,比如可直接实现数组的排序.搜索等( ...

  5. .net使用SqlBulkCopy类操作DataTable批量插入数据库数据,然后分页查询坑

    在使用SqlBulkCopy类操作DataTable批量插入数据,这种操作插入数据的效率很高,就会导致每一条数据在保存的时间基本一样,在我们分页查询添加的数据是,使用数据的添加时间来排序就会出现每页的 ...

  6. 移动设备检测类Mobile_Detect.php

    移动设备检测类Mobile_Detect.php http://mobiledetect.net/ 分类:PHP 时间:2015年11月28日 Mobile_Detect.php是一个轻量级的开源移动 ...

  7. PDF.NET数据开发框架实体类操作实例

    PDF.NET数据开发框架实体类操作实例(MySQL)的姊妹篇,两者使用了同一个测试程序,不同的只是使用的类库和数据库不同,下面说说具体的使用过程. 1,首先在App.config文件中配置数据库连接 ...

  8. iostat相关参数说明——await:平均每次设备I/O操作的等待时间 (毫秒),如果%util接近 100%,说明产生的I/O请求太多

    iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视.它的特点是汇报磁盘活动统计情况,同时也会汇报出 CPU使用情况.同vmstat一样, ...

  9. 使用File类操作文件或目录的属性

    在学I/O流之前,我先总结一下使用File类操作文件或目录的属性. package com.File; import java.io.File; import java.io.IOException; ...

随机推荐

  1. react-echarts之折线图的显示

    react中想要实现折线图和饼图的功能,需要引入react-echarts包,然后再实现折线图的功能.我这里引用的版本是:0.1.1.其他的写法参echarts官网即可.下面详细讲解的是我在react ...

  2. dagger2记录篇

    作为一个码农,什么都不用多讲,贴代码 build project build module Application public class App extends Application { pri ...

  3. LintCode389.判断数独是否合法

    LintCode简单题:判断数独是否合法 问题描述: 请判定一个数独是否有效. 该数独可能只填充了部分数字,其中缺少的数字用 . 表示. 注意事项: 一个合法的数独(仅部分填充)并不一定是可解的.我们 ...

  4. JavaScript & PHP模仿C#中string.format效果

    1.JavaScript function stringformat() { var args = Array.prototype.slice.call(arguments); if (args.le ...

  5. Linux基础练习题(三)

    1.显示当前系统上root.fedora或user1用户的默认shell: [root@www ~]# egrep "^(root|fedora|user1)" /etc/pass ...

  6. bash编程之多分支if 语句及for循环

    第十七章.bash编程之多分支if 语句及for循环 if语句三种格式 多分支if语句练习 for循环 17.1.if语句的三种格式 单分支if语句 if condition;then 条件为真执行的 ...

  7. 基于面向对象的图片轮播(js原生代码)

    无论你想走多远,你都需要不断地走下去.前端最精华的便是原生的js,这也是我们前端工程师的技术分层的重要指标,也提现这你的代码能力,开发的水平.废话不多说,进入今天的主要分享————基于面向对象思想的图 ...

  8. hdu5651 xiaoxin juju needs help (多重集的全排列+逆元)

    xiaoxin juju needs help 题意:给你一个字符串,求打乱字符后,有多少种回文串.                      (题于文末) 知识点: n个元素,其中a1,a2,··· ...

  9. 轻量级C#编辑器RoslynPad

    简介 RoslynPad是一个Apache 2.0协议开源的轻量级C#编辑器.支持自动完成,语法提示,修改建议等功能.很适合平时随手写个C#程序看看运行结果. 目前版本:0.10.1,无需保存也可以运 ...

  10. ubuntu-Linux系统读取USB摄像头数据(uvc)

    这几天在做小车的过程中,需要用到图像采集.我想现在用的摄像头是UVC免驱的.根据国嵌的教程中有一个gspca摄像头的程序.我发现把gspca的采集程序用到uvc上时,在显示图像的时候提示没有huffm ...