diff --git a/Modbus.Net/Modbus.Net/BaseConnector.cs b/Modbus.Net/Modbus.Net/BaseConnector.cs
index 85c5792..b14b680 100644
--- a/Modbus.Net/Modbus.Net/BaseConnector.cs
+++ b/Modbus.Net/Modbus.Net/BaseConnector.cs
@@ -1,12 +1,102 @@
-using System.Threading.Tasks;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Nito.AsyncEx;
+using Serilog;
namespace Modbus.Net
{
- ///
- /// 基础的协议连接类
- ///
+ ///
public abstract class BaseConnector : BaseConnector
{
+ ///
+ /// 发送锁
+ ///
+ protected abstract AsyncLock Lock { get; }
+
+ ///
+ /// 是否为全双工
+ ///
+ public bool IsFullDuplex { get; }
+
+ ///
+ /// 发送超时时间
+ ///
+ protected abstract int TimeoutTime { get; set; }
+
+ ///
+ /// 构造器
+ ///
+ /// 发送超时时间
+ /// 是否为全双工
+ protected BaseConnector(int timeoutTime = 10000, bool isFullDuplex = true)
+ {
+ IsFullDuplex = isFullDuplex;
+ TimeoutTime = timeoutTime;
+ }
+
+ ///
+ public override async Task SendMsgAsync(byte[] message)
+ {
+ var ans = await SendMsgCtrl(message);
+ return ans?.ReceiveMessage;
+ }
+
+ ///
+ /// 发送主控
+ ///
+ /// 发送的信息
+ /// 等待信息的定义
+ protected async Task SendMsgCtrl(byte[] message)
+ {
+ MessageWaitingDef ans;
+ if (!IsFullDuplex)
+ {
+ using (await Lock.LockAsync())
+ {
+ ans = await SendMsgInner(message);
+ }
+ }
+ else
+ {
+ ans = await SendMsgInner(message);
+ }
+ return ans;
+ }
+
+ ///
+ /// 发送内部
+ ///
+ /// 发送的信息
+ /// 发送信息的定义
+ protected async Task SendMsgInner(byte[] message)
+ {
+ try
+ {
+ var messageSendingdef = Controller.AddMessage(message);
+ if (messageSendingdef != null)
+ {
+ var success = messageSendingdef.SendMutex.WaitOne(TimeoutTime);
+ if (success)
+ {
+ await SendMsgWithoutConfirm(message);
+ success = messageSendingdef.ReceiveMutex.WaitOne(TimeoutTime);
+ if (success)
+ {
+ return messageSendingdef;
+ }
+ }
+ Controller.ForceRemoveWaitingMessage(messageSendingdef);
+ }
+ return null;
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, "Connector {0} Send Error.", ConnectionToken);
+ return null;
+ }
+
+ }
}
///
@@ -32,33 +122,19 @@ namespace Modbus.Net
///
protected virtual IController Controller { get; set; }
- ///
- /// 标识Connector的连接关键字
- ///
+ ///
public abstract string ConnectionToken { get; }
- ///
- /// 是否处于连接状态
- ///
+ ///
public abstract bool IsConnected { get; }
- ///
- /// 连接PLC,异步
- ///
- /// 是否连接成功
+ ///
public abstract Task ConnectAsync();
- ///
- /// 断开PLC
- ///
- /// 是否断开成功
+ ///
public abstract bool Disconnect();
- ///
- /// 带返回发送数据
- ///
- /// 需要发送的数据
- /// 是否发送成功
+ ///
public abstract Task SendMsgAsync(TParamIn message);
///
diff --git a/Modbus.Net/Modbus.Net/ComConnector.cs b/Modbus.Net/Modbus.Net/ComConnector.cs
index 1f35cc2..0da1861 100644
--- a/Modbus.Net/Modbus.Net/ComConnector.cs
+++ b/Modbus.Net/Modbus.Net/ComConnector.cs
@@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.IO.Ports;
using System.Linq;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Nito.AsyncEx;
@@ -57,17 +55,29 @@ namespace Modbus.Net
///
private readonly StopBits _stopBits;
+ ///
+ protected override int TimeoutTime { get; set; }
+
///
- /// 超时时间
+ /// 错误次数
///
- private readonly int _timeoutTime;
-
private int _errorCount;
+ ///
+ /// 获取次数
+ ///
private int _receiveCount;
-
+ ///
+ /// 发送次数
+ ///
private int _sendCount;
+ ///
+ /// 获取线程
+ ///
private Task _receiveThread;
+ ///
+ /// 获取线程关闭
+ ///
private bool _taskCancel = false;
///
@@ -84,12 +94,11 @@ namespace Modbus.Net
/// 停止位
/// 数据位
/// 超时时间
- public ComConnector(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits, int timeoutTime)
+ /// 是否为全双工
+ public ComConnector(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits, int timeoutTime = 10000, bool isFullDuplex = false) : base(timeoutTime, isFullDuplex)
{
//端口号
_com = com.Split(':')[0];
- //读超时
- _timeoutTime = timeoutTime;
//波特率
_baudRate = baudRate;
//奇偶校验
@@ -108,6 +117,9 @@ namespace Modbus.Net
private static Dictionary Connectors { get; } = new Dictionary()
;
+ ///
+ /// 连接中的连接器
+ ///
private static Dictionary Controllers { get; } = new Dictionary()
;
@@ -130,6 +142,9 @@ namespace Modbus.Net
}
}
+ ///
+ protected override AsyncLock Lock => SerialPort.Lock;
+
///
/// 连接中的连接器
///
@@ -140,6 +155,9 @@ namespace Modbus.Net
///
public override string ConnectionToken => _slave + ":" + _com;
+ ///
+ /// 获取当前连接器使用的串口
+ ///
private SerialPortLock SerialPort
{
get
@@ -150,9 +168,7 @@ namespace Modbus.Net
}
}
- ///
- /// 实现IDisposable接口
- ///
+ ///
public void Dispose()
{
Dispose(true);
@@ -292,8 +308,6 @@ namespace Modbus.Net
Log.Verbose("Com client {ConnectionToken} error count: {ErrorCount}", ConnectionToken, _errorCount);
}
- #region 发送接收数据
-
///
public override bool IsConnected
{
@@ -324,7 +338,7 @@ namespace Modbus.Net
Parity = _parity,
StopBits = _stopBits,
DataBits = _dataBits,
- ReadTimeout = _timeoutTime
+ ReadTimeout = TimeoutTime
});
}
if (!Linkers.ContainsKey(_slave))
@@ -379,16 +393,18 @@ namespace Modbus.Net
return false;
}
+ #region 发送接收数据
+
///
/// 带返回发送数据
///
/// 需要发送的数据
/// 是否发送成功
- public string SendMsg(string sendStr)
+ public async Task SendMsgAsync(string sendStr)
{
var myByte = sendStr.StringToByte_2();
- var returnBytes = SendMsg(myByte);
+ var returnBytes = await SendMsgAsync(myByte);
return returnBytes.ByteToString();
}
@@ -421,40 +437,11 @@ namespace Modbus.Net
}
}
- ///
- /// 发送数据,需要返回
- ///
- /// 发送的数据
- /// 是否发送成功
- protected byte[] SendMsg(byte[] message)
- {
- return AsyncHelper.RunSync(() => SendMsgAsync(message));
- }
-
///
public override async Task SendMsgAsync(byte[] message)
{
CheckOpen();
- var task = SendMsgInner(message).WithCancellation(new CancellationTokenSource(100000).Token);
- var ans = await task;
- if (task.IsCanceled)
- {
- Controller.ForceRemoveWaitingMessage(ans);
- return null;
- }
- return ans.ReceiveMessage;
- }
-
- private async Task SendMsgInner(byte[] message)
- {
- using (await SerialPort.Lock.LockAsync())
- {
- var messageSendingdef = Controller.AddMessage(message);
- messageSendingdef.SendMutex.WaitOne();
- await SendMsgWithoutConfirm(message);
- messageSendingdef.ReceiveMutex.WaitOne();
- return messageSendingdef;
- }
+ return await base.SendMsgAsync(message);
}
///
diff --git a/Modbus.Net/Modbus.Net/FifoController.cs b/Modbus.Net/Modbus.Net/FifoController.cs
index bb4c99d..0b8267b 100644
--- a/Modbus.Net/Modbus.Net/FifoController.cs
+++ b/Modbus.Net/Modbus.Net/FifoController.cs
@@ -44,19 +44,17 @@ namespace Modbus.Net
}
lock (WaitingMessages)
{
- if (_currentSendingPos == null)
- {
- if (WaitingMessages.Count > 0)
- {
- _currentSendingPos = WaitingMessages.First();
- }
- }
if (_currentSendingPos != null)
{
- _currentSendingPos.SendMutex.Set();
- _currentSendingPos = WaitingMessages.Count <= 1
- ? null
- : WaitingMessages[WaitingMessages.IndexOf(_currentSendingPos) + 1];
+ if (WaitingMessages.Count <= 0)
+ {
+ _currentSendingPos = null;
+ }
+ if (WaitingMessages.Count > WaitingMessages.IndexOf(_currentSendingPos) + 1)
+ {
+ _currentSendingPos = WaitingMessages[WaitingMessages.IndexOf(_currentSendingPos) + 1];
+ _currentSendingPos.SendMutex.Set();
+ }
}
}
}
diff --git a/Modbus.Net/Modbus.Net/IConnector.cs b/Modbus.Net/Modbus.Net/IConnector.cs
index 121ec4b..d570a3a 100644
--- a/Modbus.Net/Modbus.Net/IConnector.cs
+++ b/Modbus.Net/Modbus.Net/IConnector.cs
@@ -5,7 +5,7 @@ namespace Modbus.Net
///
/// Эӽӿ
///
- public interface IConnector
+ public interface IConnector
{
///
/// ʶConnectorӹؼ
diff --git a/Modbus.Net/Modbus.Net/MatchController.cs b/Modbus.Net/Modbus.Net/MatchController.cs
index 8fed36a..a4f00f5 100644
--- a/Modbus.Net/Modbus.Net/MatchController.cs
+++ b/Modbus.Net/Modbus.Net/MatchController.cs
@@ -56,14 +56,20 @@ namespace Modbus.Net
if (WaitingMessages.Count > 0)
{
_currentSendingPos = WaitingMessages.First();
+ _currentSendingPos.SendMutex.Set();
}
}
if (_currentSendingPos != null)
{
- _currentSendingPos.SendMutex.Set();
- _currentSendingPos = WaitingMessages.Count <= 1
- ? null
- : WaitingMessages[WaitingMessages.IndexOf(_currentSendingPos) + 1];
+ if (WaitingMessages.Count <= 0)
+ {
+ _currentSendingPos = null;
+ }
+ if (WaitingMessages.Count > WaitingMessages.IndexOf(_currentSendingPos) + 1)
+ {
+ _currentSendingPos = WaitingMessages[WaitingMessages.IndexOf(_currentSendingPos) + 1];
+ _currentSendingPos.SendMutex.Set();
+ }
}
}
}
diff --git a/Modbus.Net/Modbus.Net/TcpConnector.cs b/Modbus.Net/Modbus.Net/TcpConnector.cs
index b55234a..bdcbe9b 100644
--- a/Modbus.Net/Modbus.Net/TcpConnector.cs
+++ b/Modbus.Net/Modbus.Net/TcpConnector.cs
@@ -3,6 +3,7 @@ using System.Linq;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
+using Nito.AsyncEx;
using Serilog;
namespace Modbus.Net
@@ -61,22 +62,17 @@ namespace Modbus.Net
/// Ip地址
/// 端口
/// 超时时间
- public TcpConnector(string ipaddress, int port, int timeoutTime)
+ public TcpConnector(string ipaddress, int port, int timeoutTime = 10000) : base(timeoutTime)
{
_host = ipaddress;
_port = port;
- TimeoutTime = timeoutTime;
}
- ///
- /// 连接关键字
- ///
+ ///
public override string ConnectionToken => _host;
- ///
- /// 超时时间
- ///
- public int TimeoutTime
+ ///
+ protected override int TimeoutTime
{
get =>
_timeoutTime;
@@ -88,14 +84,13 @@ namespace Modbus.Net
}
}
- ///
- /// 是否已经连接
- ///
+ ///
public override bool IsConnected => _socketClient?.Client != null && _socketClient.Connected;
- ///
- /// 实现IDisposable接口
- ///
+ ///
+ protected override AsyncLock Lock { get; } = new AsyncLock();
+
+ ///
public void Dispose()
{
Dispose(true);
@@ -141,10 +136,7 @@ namespace Modbus.Net
Dispose(false);
}
- ///
- /// 连接
- ///
- /// 是否连接成功
+ ///
public override async Task ConnectAsync()
{
if (_socketClient != null)
@@ -184,10 +176,7 @@ namespace Modbus.Net
}
}
- ///
- /// 断开
- ///
- /// 是否断开成功
+ ///
public override bool Disconnect()
{
if (_socketClient == null)
@@ -211,36 +200,7 @@ namespace Modbus.Net
}
}
- ///
- /// 发送数据,需要返回
- ///
- /// 发送的数据
- /// 是否发送成功
- public override async Task SendMsgAsync(byte[] message)
- {
- var task = SendMsgInner(message).WithCancellation(new CancellationTokenSource(10000).Token);
- var ans = await task;
- if (task.IsCanceled)
- {
- Controller.ForceRemoveWaitingMessage(ans);
- return null;
- }
- return ans.ReceiveMessage;
- }
-
- private async Task SendMsgInner(byte[] message)
- {
- var messageSendingdef = Controller.AddMessage(message);
- messageSendingdef.SendMutex.WaitOne();
- await SendMsgWithoutConfirm(message);
- messageSendingdef.ReceiveMutex.WaitOne();
- return messageSendingdef;
- }
-
- ///
- /// 发送信息,不进行返回确认
- ///
- /// 发送的信息
+ ///
protected override async Task SendMsgWithoutConfirm(byte[] message)
{
var datagram = message;
@@ -265,17 +225,13 @@ namespace Modbus.Net
}
}
- ///
- /// 启动获取线程
- ///
+ ///
protected override void ReceiveMsgThreadStart()
{
_receiveThread = Task.Run(ReceiveMessage);
}
- ///
- /// 停止获取线程
- ///
+ ///
protected override void ReceiveMsgThreadStop()
{
_taskCancel = true;