Commit 4e5817fa authored by 潘栩锋's avatar 潘栩锋 🚴

添加 7E协议支持批量包发送,不等回复已经发送

parent 59014699
This diff is collapsed.
......@@ -190,7 +190,7 @@ namespace GeneralGommunication
if (!IsRunning)
return;
IsRunning = false;
IsConnected = false;
cancellation.Cancel();
sp.Close();
}
......
......@@ -48,9 +48,9 @@ namespace GeneralGommunication
public event PropertyChangedEventHandler PropertyChanged;
Socket sock;
CancellationTokenSource cancellation;
CancellationTokenSource cancellation_waitforSend;
CancellationTokenSource cts_readTask;
CancellationTokenSource cts_waitForSend;
CancellationTokenSource cts_sendTask;
public GComm_TcpClient()
{
......@@ -64,9 +64,9 @@ namespace GeneralGommunication
if (IsRunning)
return;
IsRunning = true;
cancellation = new CancellationTokenSource();
cts_readTask = new CancellationTokenSource();
Task.Factory.StartNew(OnTask, cancellation.Token);
Task.Factory.StartNew(OnTask, cts_readTask.Token);
}
/// <summary>
......@@ -77,8 +77,8 @@ namespace GeneralGommunication
if (!IsRunning)
return;
IsRunning = false;
cancellation.Cancel();
IsConnected = false;
cts_readTask.Cancel();
if (sock != null && sock.Connected)
{
sock.Close();
......@@ -88,7 +88,7 @@ namespace GeneralGommunication
void OnTask()
{
while (!cancellation.IsCancellationRequested)
while (!cts_readTask.IsCancellationRequested)
{
ConnectTask();
......@@ -96,17 +96,27 @@ namespace GeneralGommunication
{
sendBuf.Clear();
//启动发送task
Task.Factory.StartNew(SendTask, cancellation.Token);
cts_sendTask = new CancellationTokenSource();
var sendtask = Task.Factory.StartNew(SendTask, cts_sendTask.Token);
//进入接收task
ReceiveTask();
//退出了,肯定连接断开了
//需要等待 SendTask 也退出了
cts_sendTask.Cancel();
sendtask.Wait();
if (sock != null)
{
sock.Close();
}
}
//休息一会儿,在重连
try
{
Task.Delay(2000, cancellation.Token).Wait();
Task.Delay(2000, cts_readTask.Token).Wait();
}
catch (Exception e)
{
......@@ -126,14 +136,12 @@ namespace GeneralGommunication
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Blocking = true;
//1秒内,需要收到信息
sock.ReceiveTimeout = 1000;
//1秒内,必须发送完
sock.SendTimeout = 1000;
while (!cancellation.IsCancellationRequested)
while (!cts_readTask.IsCancellationRequested)
{
try
{
......@@ -150,7 +158,7 @@ namespace GeneralGommunication
}
try
{
Task.Delay(2000, cancellation.Token).Wait();
Task.Delay(2000, cts_readTask.Token).Wait();
}
catch (Exception e)
{
......@@ -166,7 +174,7 @@ namespace GeneralGommunication
void ReceiveTask()
{
byte[] buf = new byte[0x10000];
while (!cancellation.IsCancellationRequested)
while (!cts_readTask.IsCancellationRequested)
{
int len;
try
......@@ -196,10 +204,7 @@ namespace GeneralGommunication
DataReceived?.Invoke(this, buf.Take(len).ToArray());
}
if (sock != null)
{
sock.Close();
}
IsConnected = false;
}
......@@ -208,14 +213,24 @@ namespace GeneralGommunication
/// </summary>
void SendTask()
{
while (!cancellation.IsCancellationRequested)
while (!cts_sendTask.IsCancellationRequested)
{
while (sendBuf.Count > 0)
CancellationTokenSource cts3;
while (true)
{
byte[] buffer;
lock (sendBuf)
{
if (sendBuf.Count <= 0)
break;
buffer = sendBuf.ToArray();
}
int slen;
try
{
slen = sock.Send(sendBuf.ToArray());
slen = sock.Send(buffer);
}
catch (Exception e)
{
......@@ -223,26 +238,42 @@ namespace GeneralGommunication
IsConnected = false;
break;
}
if (slen > 0)
sendBuf.RemoveRange(0, slen);
else if (slen <= 0)
if (slen <= 0)
{
//连接断开了
IsConnected = false;
break;
}
else
{
lock (sendBuf)
{
sendBuf.RemoveRange(0, slen);
}
}
}
//重新等 下次被呼醒
cancellation_waitforSend = new CancellationTokenSource();
lock (sendBuf)
{
// 呼醒 发送task
if (cts_waitForSend == null)
{
cts_waitForSend = new CancellationTokenSource();
}
//cts_waitForSend 与 cts_sendTask 合体, 任意一个都会呼醒 delay
cts3 = CancellationTokenSource.CreateLinkedTokenSource(cts_waitForSend.Token, cts_sendTask.Token);
}
try
{
Task.Delay(-1, cancellation_waitforSend.Token).Wait();
Task.Delay(-1, cts3.Token).Wait();
}
catch (Exception e)
{
//被打断, 有数据需要发送
}
cts_waitForSend = null;
}
}
/// <summary>
......@@ -259,13 +290,19 @@ namespace GeneralGommunication
if (!IsConnected)
return;
lock (sendBuf)
{
//放入,发送缓存区
sendBuf.AddRange(buf);
//放入,发送缓存区
sendBuf.AddRange(buf);
//呼醒 发送task
cancellation_waitforSend.Cancel();
//呼醒 发送task
if (cts_waitForSend == null)
{
cts_waitForSend = new CancellationTokenSource();
}
cts_waitForSend.Cancel();
}
}
/// <summary>
......
......@@ -9,7 +9,10 @@ namespace GeneralGommunication
{
public interface IDev7E : INotifyPropertyChanged
{
#region 测量速度
#region 测量通讯速度
/// <summary>
/// 通讯速度 测量中
/// </summary>
bool IsMeasuring { get; }
/// <summary>
......@@ -18,7 +21,7 @@ namespace GeneralGommunication
double CommSpeed { get; }
/// <summary>
/// 传输速度 单位 pack/s
/// 通讯速度 单位 pack/s
/// </summary>
double PackSpeed { get; }
......@@ -100,26 +103,31 @@ namespace GeneralGommunication
/// </summary>
public class COMMREQ
{
private byte[] prefix;
/// <summary>
/// 指令 前缀
/// </summary>
public byte[] Prefix;
public string PrefixString
public byte[] Prefix
{
get { return prefix; }
set {
prefix = value;
updatePrefixString();
}
}
public string PrefixString { get; private set; }
void updatePrefixString()
{
get
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < Prefix.Count(); i++)
{
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < Prefix.Count(); i++)
{
if (Prefix[i] >= 33 || Prefix[i] <= 126)
stringBuilder.Append((char)Prefix[i]);
else
stringBuilder.Append($" 0x{Prefix[i]:X2} ");
}
return stringBuilder.ToString();
if (Prefix[i] >= 33 && Prefix[i] <= 126)
stringBuilder.Append((char)Prefix[i]);
else
stringBuilder.Append($" 0x{Prefix[i]:X2} ");
}
PrefixString = stringBuilder.ToString();
}
/// <summary>
/// 回复数据 长度, 不含前序
/// </summary>
......@@ -133,9 +141,9 @@ namespace GeneralGommunication
public delegate object ParseFuncPackHandler(byte[] pack, int dataIdx);
public ParseFuncPackHandler ParseFuncPack;
public delegate bool IsMatchHandler(COMMREQ commReq, byte[] pack, int dataIdx, object context, ref object retData);
public IsMatchHandler IsMatch;
public object IsMatchContext;
public static byte[] ToPrefix(params object[] commands)
{
List<byte> bytes = new List<byte>();
......@@ -176,13 +184,9 @@ namespace GeneralGommunication
}
public class COMMREQ_Transaction
{
/// <summary>
/// 请求
/// </summary>
public COMMREQ commReq;
public abstract class COMMREQ_TransactionBase
{
/// <summary>
/// 回复 callback
/// </summary>
......@@ -192,6 +196,25 @@ namespace GeneralGommunication
/// 上下文
/// </summary>
public object asyncContext;
}
/// <summary>
/// 交易集合包
/// </summary>
public class COMMREQ_TransactionMulti : COMMREQ_TransactionBase
{
/// <summary>
/// 交易集合
/// </summary>
public List<COMMREQ_Transaction> transactions = new List<COMMREQ_Transaction>();
}
public class COMMREQ_Transaction: COMMREQ_TransactionBase
{
/// <summary>
/// 请求
/// </summary>
public COMMREQ commReq;
/// <summary>
/// 数据
......@@ -202,5 +225,15 @@ namespace GeneralGommunication
/// 数据的object 表达,只用于调试而已
/// </summary>
public object datasObj;
/// <summary>
/// 数据已经回复
/// </summary>
public bool hasRet;
/// <summary>
/// 回复的数据,只用于调试而已
/// </summary>
public object retData;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment