Commit ebb0ddf4 张东亮

粘包问题优化

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