基本信息
源码名称:C#基于UDP欧姆龙PLC通信程序
源码大小:0.53M
文件格式:.zip
开发语言:C#
更新时间:2019-09-18
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):78630559
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
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();
}
}
}