Commit ebb0ddf4 张东亮

粘包问题优化

1 个父辈 d4bc3cf4
......@@ -76,6 +76,7 @@ namespace AGVControl
{
DgvNode.Rows[i].SetValues(CommonVar.nodeInfo[i].ToRow());
}
DgvNode.Refresh();
}));
System.GC.Collect();
}
......@@ -84,7 +85,9 @@ namespace AGVControl
{
Invoke(new Action(() =>
{
DgvNode.Rows[nodeIndex].DefaultCellStyle.ForeColor = CommonVar.nodeInfo[nodeIndex].Online ? Color.Black : Color.Red;
for (int i = 0; i < CommonVar.nodeInfo.Count; i++)
DgvNode.Rows[nodeIndex].DefaultCellStyle.ForeColor = CommonVar.nodeInfo[nodeIndex].Online ? Color.Black : Color.Red;
DgvNode.Refresh();
}));
System.GC.Collect();
}
......
......@@ -63,6 +63,13 @@ namespace AGVControl
//}
if (MessageBox.Show(this, "是否继续上一次的任务?\r\n" + Agv.Msg, "提示", MessageBoxButtons.YesNo).Equals(DialogResult.No))
{
if(Agv.IsExistShelf)
{
LogUtil.error("请将车上料架移走再开自动!");
Agv.CurJob = null;
MessageBox.Show(this,"请将车上料架移走再开自动!");
return;
}
LogUtil.info(string.Format("{0} 手动取消上一次任务:{1}", Agv.Name, Agv.Msg));
Agv.CurJob = null;
if (Agv.Place.Equals(SettingString.Standby) || Agv.Place.Equals(SettingString.AutoCharge))
......
......@@ -4,6 +4,8 @@ using System.Net;
using System.Net.Sockets;
using Common;
using System.Threading;
using System.Linq;
using System.Collections.Concurrent;
namespace DeviceLibrary
{
......@@ -257,16 +259,18 @@ namespace DeviceLibrary
}
}
}
//临时缓存
//线程安全的字典
ConcurrentDictionary<string, byte[]> dic = new ConcurrentDictionary<string, byte[]>();
/// <summary>
/// 客户端数据接收
/// </summary>
/// <param name="obj">索引</param>
private void ListenNet(object obj)
{
int sleep = 10;
int sleep = 100;
Client client = _client[(int)obj];
byte[] temp = new byte[200];
byte[] temp = new byte[127];
int time = 0;
while (client.Loop)
......@@ -278,32 +282,95 @@ namespace DeviceLibrary
if (client.Socket.Available > 0)
{
time = 0;
byte[] supBuff = null;
int count = client.Socket.Receive(temp);
byte[] buff = new byte[count];
Array.Copy(temp, 0, buff, 0, count);
ClientNode node = Decode(buff);
if (node == null)
if (!dic.TryGetValue(client.IP,out supBuff)) //第一次收到开头必须是0xAB开头的字节
{
log.Error("命令解析失败: " + HexBuff(buff));
log.Error("关闭连接,因解析失败:"+ string.Join(",",client.nodeName.ToArray()));
Offline(client);
if(temp[0].Equals(0xAB))
{
supBuff = new byte[count];
Array.Copy(temp, 0, supBuff, 0, count);
//log.Info(string.Format("start with AB receive:{0}", HexBuff(supBuff)));
}
else
{
//log.Info(string.Format("start without AB receive:{0}", HexBuff(temp)));
for (int i = 0; i < count; i++)
{
if (!temp[i].Equals(0xAB))
continue;
supBuff = new byte[count - i];
Array.Copy(temp, i, supBuff, 0, count - i);
//log.Info(string.Format("start without AB receive after filter:{0}", HexBuff(supBuff)));
break;
}
}
dic.TryAdd(client.IP, supBuff);
}
else
{
//CommonVar.log.Info("Receive[" + client.IP + "] " + node.ToText());
int idx = client.nodeName.FindIndex(s => s == node.Name);
if (idx == -1) client.nodeName.Add(node.Name);
UpdateNode(node);
byte[] tmp = new byte[count];
Array.Copy(temp, 0, tmp, 0, count);
byte[] curBuff = supBuff.Concat(tmp).ToArray();
dic.TryUpdate(client.IP,curBuff,supBuff);
supBuff = curBuff;
//log.Info(string.Format("receive:{0}",HexBuff(tmp)));
//log.Info(string.Format("buff:{0}",HexBuff(supBuff)));
//log.Info(string.Format("curBuf:{0}",HexBuff(curBuff)));
//log.Info(string.Format("dic[0]:{0}", HexBuff(dic[client.IP])));
}
List<byte> buf = new List<byte>();
for (int i = 0; i < supBuff.Length; i++)
{
if (supBuff[i].Equals(0XAB))
{
if (buf.Count > 0)
buf.Clear();
buf.Add(supBuff[i]);
}
else if (supBuff[i].Equals(0XBA))
{
buf.Add(supBuff[i]);
byte[] buff = buf.ToArray();
//Array.Copy(temp, 0, buff, 0, count);
ClientNode node = Decode(buff);
if (node == null)
{
log.Error("命令解析失败: " + HexBuff(buff));
buf.Clear();
break;
}
else
{
//CommonVar.log.Info("Receive[" + client.IP + "] " + node.ToText());
int idx = client.nodeName.FindIndex(s => s == node.Name);
if (idx == -1) client.nodeName.Add(node.Name);
UpdateNode(node);
}
if (buf.Count > 0)
buf.Clear();
}
else
{
buf.Add(supBuff[i]);
}
}
if (buf.Count > 0)//存在部分包
{
dic.TryUpdate(client.IP,buf.ToArray(),supBuff);
}
else
dic.TryRemove(client.IP, out byte[] bb);
}
else
{
time += sleep;
if (time > 60000)
if (time > 30000)
{
Offline(client);
log.Debug("[" + client.IP + "] 超过60s没有收到数据,关闭连接");
log.Debug("[" + client.IP + "] 超过30s没有收到数据,关闭连接");
}
}
}
......@@ -349,40 +416,48 @@ namespace DeviceLibrary
return buff;
}
//
/// <summary>
/// 解码
/// 解码 AB 91 123 34 78 97 109 101 34 58 34 BA AB 91 123 34 78 97 109 101 34 58 34 BA
/// </summary>
/// <param name="buff"></param>
/// <returns></returns>
private ClientNode Decode(byte[] buff)
{
int idx = 0;
if (buff[idx++] != 0xAB) return null;
try
{
if (buff[idx++] != 0xAB) return null;
byte[] temp1 = new byte[buff[idx++]];
Array.Copy(buff, idx, temp1, 0, temp1.Length);
string name = System.Text.Encoding.UTF8.GetString(temp1);
idx += temp1.Length;
byte[] temp1 = new byte[buff[idx++]];
Array.Copy(buff, idx, temp1, 0, temp1.Length);
string name = System.Text.Encoding.UTF8.GetString(temp1);
idx += temp1.Length;
temp1 = new byte[buff[idx++]];
Array.Copy(buff, idx, temp1, 0, temp1.Length);
string mark = System.Text.Encoding.UTF8.GetString(temp1);
idx += temp1.Length;
temp1 = new byte[buff[idx++]];
Array.Copy(buff, idx, temp1, 0, temp1.Length);
string mark = System.Text.Encoding.UTF8.GetString(temp1);
idx += temp1.Length;
temp1 = new byte[buff[idx++]];
Array.Copy(buff, idx, temp1, 0, temp1.Length);
string rfid = System.Text.Encoding.UTF8.GetString(temp1);
idx += temp1.Length;
temp1 = new byte[buff[idx++]];
Array.Copy(buff, idx, temp1, 0, temp1.Length);
string rfid = System.Text.Encoding.UTF8.GetString(temp1);
idx += temp1.Length;
eNodeStatus action = (eNodeStatus)buff[idx++];
ClientLevel level = (ClientLevel)buff[idx++];
eNodeStatus action = (eNodeStatus)buff[idx++];
ClientLevel level = (ClientLevel)buff[idx++];
ClientNode node = new ClientNode(name, rfid, action, mark, level);
ClientNode node = new ClientNode(name, rfid, action, mark, level);
if (buff[idx] != 0xBA)
if (buff[idx] != 0xBA)
return null;
return node;
}
catch
{
return null;
return node;
}
}
private void UpdateNode(ClientNode node)
......@@ -399,7 +474,6 @@ namespace DeviceLibrary
CommonVar.nodeInfo[idx].Online = true;
NodeOnline?.Invoke(idx);
}
NodeChanged?.Invoke(idx);
if (CommonVar.nodeInfo[idx].CheckNodeStateChanged(node))
{
log.Info("节点状态更新 " + node.StatetText());
......
......@@ -672,7 +672,7 @@ namespace DeviceLibrary
ping.Dispose();
if (result.Status != System.Net.NetworkInformation.IPStatus.Success)
{
log.Error("Ping " + ip + " 请求没有响应");
log.Debug("Ping " + ip + " 请求没有响应");
return false;
}
return true;
......
......@@ -194,14 +194,14 @@ namespace DeviceLibrary
curJobStep.Msg = msg;
return new ChargeJob(TargetPlace);
}
else
{
curJobStep.ToNextStep(EXECUTE_STEP.P2_WAIT_REACH_SHELF_PLACE);
runInfo = string.Format("线体[{0}]允许出料信号[{1}]超时{2}秒,重发出料请求", TargetPlace, eNodeStatus.MayLeave, timeOutTime.ToString("f2"));
msg += string.Format("线体[{0}]允许出料信号[{1}]超时15S,重发出料请求", TargetPlace, eNodeStatus.MayLeave);
curJobStep.Msg = msg;
//去待机位
}
//else
//{
// curJobStep.ToNextStep(EXECUTE_STEP.P2_WAIT_REACH_SHELF_PLACE);
// runInfo = string.Format("线体[{0}]允许出料信号[{1}]超时{2}秒,重发出料请求", TargetPlace, eNodeStatus.MayLeave, timeOutTime.ToString("f2"));
// msg += string.Format("线体[{0}]允许出料信号[{1}]超时15S,重发出料请求", TargetPlace, eNodeStatus.MayLeave);
// curJobStep.Msg = msg;
// //去待机位
//}
}
}
else if (curJobStep.IsStep(EXECUTE_STEP.P5_WAIT_SHELF_IN_AGV))
......
......@@ -62,7 +62,8 @@ namespace DeviceLibrary
}
}
//检查紧急出料入口需要空料串
if (FindNeedEnterMission(currentAgv, SettingString.T4_1,ClientLevel.Middle,false))
if (FindNeedEnterMission(currentAgv, SettingString.T4_1))//FindNeedEnterMission(currentAgv, SettingString.T4_1,ClientLevel.Middle,false) ||
//FindNeedEnterMission(currentAgv, SettingString.T4_1, ClientLevel.High, false)
{
if (FindNeedLeaveMission(currentAgv, SettingString.T1_2, out rfid, SettingString.ReelString_RFID_Prefix))
......@@ -160,10 +161,14 @@ namespace DeviceLibrary
return new GetShelfJob(currentAgv.Place, SettingString.T5_2, rfid);
}
}
//FindNeedEnterMission(currentAgv, SettingString.T1_1, ClientLevel.Middle, false) || FindNeedEnterMission(currentAgv, SettingString.T2_1, ClientLevel.Middle, false) ||
// FindNeedEnterMission(currentAgv, SettingString.T3_1, ClientLevel.Middle, false) || FindNeedEnterMission(currentAgv, SettingString.T5_1, ClientLevel.Middle, false) ||
// FindNeedEnterMission(currentAgv, SettingString.T1_1, ClientLevel.High, false) || FindNeedEnterMission(currentAgv, SettingString.T2_1, ClientLevel.High, false) ||
// FindNeedEnterMission(currentAgv, SettingString.T3_1, ClientLevel.High, false) || FindNeedEnterMission(currentAgv, SettingString.T5_1, ClientLevel.High, false)
//检查入料口需要满料,且点料机D2/A1出满料串
if (FindNeedEnterMission(currentAgv, SettingString.T1_1,ClientLevel.Middle,false) || FindNeedEnterMission(currentAgv, SettingString.T2_1, ClientLevel.Middle, false) ||
FindNeedEnterMission(currentAgv, SettingString.T3_1, ClientLevel.Middle, false) || FindNeedEnterMission(currentAgv, SettingString.T5_1, ClientLevel.Middle, false))
if (FindNeedEnterMission(currentAgv, SettingString.T1_1) || FindNeedEnterMission(currentAgv, SettingString.T2_1) ||
FindNeedEnterMission(currentAgv, SettingString.T3_1) || FindNeedEnterMission(currentAgv, SettingString.T5_1))
{
if (FindNeedLeaveMission(currentAgv, SettingString.D2, out rfid))
{
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!