实例介绍
【实例简介】
【实例截图】
【核心代码】
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
namespace CableRobot.Fins
{
/// <summary>
/// Allows to write and read PLC memory 允许读写PLC内存
/// </summary>
public class FinsClient : IDisposable
{
/// <summary>
/// 声明类对象
/// </summary>
private readonly CancellationTokenSource _cancellationTokenSource;
private readonly CancellationToken _cancellationToken;
private readonly UdpClient _udpClient;
private readonly FinsResponse[] _responses = new FinsResponse[256];
private readonly Thread _readerThread;
private readonly object _lockObject = new object();
private byte _sid;
public FinsClient(IPEndPoint remoteIpEndPoint)/////
{
///创建一个UdpClient对象,0表示系统自动分配发送端口
_udpClient = new UdpClient();
_udpClient.Connect(remoteIpEndPoint);
_cancellationTokenSource = new CancellationTokenSource();
_cancellationToken = _cancellationTokenSource.Token;///用于监听是否取消每一个任务或线程
///创建 _readerThread线程。此处用线程是为了避免阻塞
_readerThread = new Thread(ReadWorker);
///调用Staet()函数启动 _readerThread线程
_readerThread.Start();
///int Array.Length函数:获取数组所有维度中元素的总数
for (int i = 0; i < _responses.Length; i )
_responses[i] = new FinsResponse((byte)i, null);
Timeout = TimeSpan.FromSeconds(2);
}
/// <summary>
/// Gets or sets response timeout设置相应超时
/// </summary>
public TimeSpan Timeout { get; set; }/////
public void Close()/////
{
_cancellationTokenSource.Cancel();
///阻塞调用线程,直到此实例所表示的线程终止,
_readerThread.Join();
}
/// <summary>
/// Syncroniously reads specified number of ushorts starting from specified address in data memory
/// 从数据内存中指定的地址开始同步读取指定数量的ushort
/// </summary>
/// <param name="startAddress">Address to start to read from</param>
/// <param name="count">Number of ushorts to read</param>
/// <returns>Read data</returns>
public ushort[] ReadData(ushort startAddress, ushort count)/////
{
var sid = IncrementSid();
var cmd = FinsDriver.ReadDataCommand(new Header(sid, true), startAddress, count);
return Read(sid, cmd);
}
/// <summary>
/// Syncroniously reads specified number of ushorts starting from specified address in work memory
/// </summary>
/// <param name="startAddress">Address to start to read from</param>
/// <param name="count">Number of ushorts to read</param>
/// <returns>Read data</returns>
public ushort[] ReadWork(ushort startAddress, ushort count)/////
{
var sid = IncrementSid();
var cmd = FinsDriver.ReadWorkCommand(new Header(sid, true), startAddress, count);
return Read(sid, cmd);
}
/// <summary>
/// Syncroniously writes specified data to specified address of data memory
/// </summary>
/// <param name="startAddress">Address to start write to</param>
/// <param name="data">Data to write</param>
public void WriteData(ushort startAddress, ushort[] data)/////
{
var sid = IncrementSid();
var cmd = FinsDriver.WriteDataCommand(new Header(sid, true), startAddress, data);
Write(sid, cmd);
}
/// <summary>
/// Syncroniously writes specified data to specified address of work memory
/// </summary>
/// <param name="startAddress">Address to start write to</param>
/// <param name="data">Data to write</param>
public void WriteWork(ushort startAddress, ushort[] data)/////
{
var sid = IncrementSid();
var cmd = FinsDriver.WriteWorkCommand(new Header(sid, true), startAddress, data);
Write(sid, cmd);
}
/// <summary>
/// Asynchronously reads specified number of ushorts starting from specified address in data memory
/// </summary>
/// <param name="startAddress">Address to start to read from</param>
/// <param name="count">Number of ushorts to read</param>
/// <returns>Read data</returns>
public async Task<ushort[]> ReadDataAsync(ushort startAddress, ushort count)
{
var sid = IncrementSid();
var cmd = FinsDriver.ReadDataCommand(new Header(sid, true), startAddress, count);
return (await CommandAsync(sid, cmd)).Data;
}
/// <summary>
/// Asynchronously writes specified data to specified address of data memory
/// </summary>
/// <param name="startAddress">Address to start to write to</param>
/// <param name="data">Data to write</param>
public async Task WriteDataAsync(ushort startAddress, ushort[] data)
{
var sid = IncrementSid();
var cmd = FinsDriver.WriteDataCommand(new Header(sid, true), startAddress, data);
await CommandAsync(sid, cmd);
}
/// <summary>
/// Writes specified data to specified address of data memory without
/// </summary>
/// <param name="startAddress">Address to start to read from</param>
/// <param name="count">Number of ushorts to read</param>
public void WriteDataNoResponse(ushort startAddress, ushort[] data)
{
var sid = IncrementSid();
var cmd = FinsDriver.WriteDataCommand(new Header(sid, false), startAddress, data);
_udpClient.SendAsync(cmd, cmd.Length);
}
private byte IncrementSid()
{
byte sid;
lock (_lockObject)
{
_sid ;
sid = _sid;
}
_responses[sid].Reset();
return sid;
}
private ushort[] Read(byte sid, byte[] cmd)
{
if (_udpClient.Send(cmd, cmd.Length) != cmd.Length)
throw new Exception();
if (!_responses[sid].WaitEvent.WaitOne(Timeout))
throw new TimeoutException();
return _responses[sid].Data;
}
private void Write(byte sid, byte[] cmd)
{
if (_udpClient.Send(cmd, cmd.Length) != cmd.Length)
throw new Exception();
if (!_responses[sid].WaitEvent.WaitOne(Timeout))
throw new TimeoutException();
}
private async Task<FinsResponse> CommandAsync(byte sid, byte[] cmd)
{
if (await _udpClient.SendAsync(cmd, cmd.Length) != cmd.Length)
throw new Exception();
if (!_responses[sid].WaitEvent.WaitOne(Timeout))
throw new TimeoutException();
return _responses[sid];
}
private void ReadWorker()
{
try
{
while (true)
{
var task = _udpClient.ReceiveAsync(); ///返回由远程主机异步发送的UDP数据报
task.Wait(_cancellationToken);
if (task.IsFaulted)
throw new AggregateException(task.Exception);
FinsDriver.ProcessResponse(task.Result, _responses);
}
}
catch (OperationCanceledException)
{
}
}
public void Dispose()
{
_cancellationTokenSource?.Cancel();
_readerThread?.Join();
_udpClient?.Dispose();
}
}
}
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论