Commit 59b2af93 张东亮

11

1 个父辈 53cce1c4
正在显示 103 个修改的文件 包含 1264 行增加183 行删除
此文件类型无法预览
...@@ -31,16 +31,18 @@ ...@@ -31,16 +31,18 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="log4net"> <Reference Include="log4net, Version=2.0.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>.\log4net.dll</HintPath> <HintPath>..\packages\log4net.2.0.12\lib\net45\log4net.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>.\Newtonsoft.Json.dll</HintPath> <HintPath>.\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
...@@ -55,5 +57,8 @@ ...@@ -55,5 +57,8 @@
<Compile Include="Node.cs" /> <Compile Include="Node.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>
\ No newline at end of file \ No newline at end of file
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
...@@ -10,6 +11,51 @@ namespace Agv ...@@ -10,6 +11,51 @@ namespace Agv
public class Common public class Common
{ {
//包开始字节
public static byte[] headPack = new byte[] { 0xAB, 0xBA };
public static int headSize = 6;//包头识别符2+包头长度4
/// <summary>
/// 节点信息解析方式,默认多个节点同时收发并解析
/// </summary>
public static bool EnDecodeSingleNode = false;
public static bool CheckHeadChar(byte[] head, out int starIdx)
{
starIdx = -1;
for (int i = 0; i < head.Length - headPack.Length+1; i++)
{
int j = 0;
for (j = 0; j < headPack.Length; j++)
{
if (!head[i + j].Equals(headPack[j]))
break;
}
if (j == headPack.Length)
{
starIdx = i;
return true;
}
}
return false;
}
public static string HexBuff(byte[] buff)
{
string s = "";
if (buff == null) return s;
for (int i = 0; i < buff.Length; i++)
s += buff[i].ToString("X2") + " ";
return s;
}
public static string HexBuffWithoutSpace(byte[] buff)
{
string s = "";
if (buff == null) return s;
for (int i = 0; i < buff.Length; i++)
s += buff[i].ToString("X2");
return s;
}
/// <summary> /// <summary>
/// 编码 /// 编码
/// </summary> /// </summary>
...@@ -19,9 +65,11 @@ namespace Agv ...@@ -19,9 +65,11 @@ namespace Agv
{ {
try try
{ {
string json =JsonHelper.SerializeObject(node); string json = JsonHelper.SerializeObject(node);
log.debug(string.Format("Encode[{0}]", json)); log.debug(string.Format("Encode[{0}]", json));
byte[] buff = System.Text.Encoding.UTF8.GetBytes(json); byte[] body = Encoding.UTF8.GetBytes(json);
byte[] bodySize = IntToByteArray(body.Length);
byte[] buff = headPack.Concat(bodySize).Concat(body).ToArray();
return buff; return buff;
} }
catch (Exception ex) catch (Exception ex)
...@@ -42,7 +90,12 @@ namespace Agv ...@@ -42,7 +90,12 @@ namespace Agv
{ {
string json = JsonHelper.SerializeObject(nodes); string json = JsonHelper.SerializeObject(nodes);
log.debug(string.Format("Encode[{0}]", json)); log.debug(string.Format("Encode[{0}]", json));
byte[] buff = System.Text.Encoding.UTF8.GetBytes(json); byte[] body = Encoding.UTF8.GetBytes(json);
byte[] bodySize = IntToByteArray(body.Length);
byte[] buff = headPack.Concat(bodySize).Concat(body).ToArray();
log.debug(string.Format("headPack:{0}", Common.HexBuff(Common.headPack)));
log.debug(string.Format("bodysize:{0}[{1}]", Common.HexBuff(bodySize), body.Length));
log.debug(string.Format("body:{0}", Common.HexBuff(body)));
return buff; return buff;
} }
catch (Exception ex) catch (Exception ex)
...@@ -94,6 +147,23 @@ namespace Agv ...@@ -94,6 +147,23 @@ namespace Agv
return null; return null;
} }
} }
//将数字转换成字节数组
//由数字创建字节数组
public static byte[] IntToByteArray(Int32 src)
{
//创建内存流MemoryStream,stream作为存放 二进制数据 的缓存
using (MemoryStream stream = new MemoryStream())
{
//创建一个BinaryWriter来写二进制数据到stream
using (BinaryWriter write = new BinaryWriter(stream))
{
write.Write(src);//将十进制数字src写到stream中,
return stream.ToArray();//将写到stream中的二进制数据转为字节数组
}
}
}
} }
/// <summary> /// <summary>
......
...@@ -27,5 +27,9 @@ namespace Agv ...@@ -27,5 +27,9 @@ namespace Agv
{ {
LOGGER.Error(errorMsg, ex); LOGGER.Error(errorMsg, ex);
} }
public static void warn(string warn)
{
LOGGER.Warn(warn);
}
} }
} }
...@@ -36,7 +36,10 @@ namespace Agv ...@@ -36,7 +36,10 @@ namespace Agv
/// 料架类型 /// 料架类型
/// </summary> /// </summary>
public ClientShelf Shelf { set; get; } = ClientShelf.None; public ClientShelf Shelf { set; get; } = ClientShelf.None;
/// <summary>
/// 节点优先级,值越大优先级越低。默认值为0
/// </summary>
public int Priority { get; set; } = 0;
public Node(string name,string rfid="",string mark="",ClientAction action = ClientAction.None, public Node(string name,string rfid="",string mark="",ClientAction action = ClientAction.None,
ClientLevel level = ClientLevel.Low,ClientShelf shelfType = ClientShelf.None,ClientType clientType = ClientType.None) ClientLevel level = ClientLevel.Low,ClientShelf shelfType = ClientShelf.None,ClientType clientType = ClientType.None)
{ {
......
此文件的差异太大,无法显示。
此文件类型无法预览
35c3965847f80e2b5445247f75e89b4af09c6e34 196296d5e062c8186fa3b6a47ddf53dd7eeaeb33
...@@ -2,7 +2,9 @@ E:\Neotel\Projects\Gitee\AGV-Com\Agv\bin\Debug\Agv.dll ...@@ -2,7 +2,9 @@ E:\Neotel\Projects\Gitee\AGV-Com\Agv\bin\Debug\Agv.dll
E:\Neotel\Projects\Gitee\AGV-Com\Agv\bin\Debug\Agv.pdb E:\Neotel\Projects\Gitee\AGV-Com\Agv\bin\Debug\Agv.pdb
E:\Neotel\Projects\Gitee\AGV-Com\Agv\bin\Debug\log4net.dll E:\Neotel\Projects\Gitee\AGV-Com\Agv\bin\Debug\log4net.dll
E:\Neotel\Projects\Gitee\AGV-Com\Agv\bin\Debug\Newtonsoft.Json.dll E:\Neotel\Projects\Gitee\AGV-Com\Agv\bin\Debug\Newtonsoft.Json.dll
E:\Neotel\Projects\Gitee\AGV-Com\Agv\bin\Debug\log4net.xml
E:\Neotel\Projects\Gitee\AGV-Com\Agv\obj\Debug\Agv.csproj.CoreCompileInputs.cache E:\Neotel\Projects\Gitee\AGV-Com\Agv\obj\Debug\Agv.csproj.CoreCompileInputs.cache
E:\Neotel\Projects\Gitee\AGV-Com\Agv\obj\Debug\Agv.csproj.CopyComplete E:\Neotel\Projects\Gitee\AGV-Com\Agv\obj\Debug\Agv.csproj.CopyComplete
E:\Neotel\Projects\Gitee\AGV-Com\Agv\obj\Debug\Agv.dll E:\Neotel\Projects\Gitee\AGV-Com\Agv\obj\Debug\Agv.dll
E:\Neotel\Projects\Gitee\AGV-Com\Agv\obj\Debug\Agv.pdb E:\Neotel\Projects\Gitee\AGV-Com\Agv\obj\Debug\Agv.pdb
E:\Neotel\Projects\Gitee\AGV-Com\Agv\obj\Debug\Agv.csprojAssemblyReference.cache
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.12" targetFramework="net472" />
</packages>
\ No newline at end of file \ No newline at end of file
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
...@@ -22,7 +23,6 @@ namespace Agv ...@@ -22,7 +23,6 @@ namespace Agv
private Thread tRecon; private Thread tRecon;
private string SERVER_IP; //远程IP地址 private string SERVER_IP; //远程IP地址
private int SERVER_PORT; //端口 private int SERVER_PORT; //端口
private bool _IsEecodeSingleNode = false;//是否编码单个节点(默认编码多个节点)
/// <summary> /// <summary>
/// 小车接收事件委托 /// 小车接收事件委托
/// </summary> /// </summary>
...@@ -54,12 +54,10 @@ namespace Agv ...@@ -54,12 +54,10 @@ namespace Agv
/// <summary> /// <summary>
/// AGV客户端 /// AGV客户端
/// </summary> /// </summary>
/// <param name="_IsEecodeSingleNode">编码方式,默认编码多个节点</param> public AgvClient()
public AgvClient(bool _IsEecodeSingleNode = false)
{ {
_node = new List<Node>(); _node = new List<Node>();
_nodeNoneState = new List<Node>(); _nodeNoneState = new List<Node>();
this._IsEecodeSingleNode = _IsEecodeSingleNode;
} }
/// <summary> /// <summary>
...@@ -96,7 +94,6 @@ namespace Agv ...@@ -96,7 +94,6 @@ namespace Agv
//Open(); //Open();
tListen.Start(); tListen.Start();
tSend.Start(); tSend.Start();
Agv.log.info("连接服务器");
} }
/// <summary> /// <summary>
...@@ -107,12 +104,12 @@ namespace Agv ...@@ -107,12 +104,12 @@ namespace Agv
CancelState = true; CancelState = true;
_loopClient = false; _loopClient = false;
_loopRecon = false; _loopRecon = false;
SendStatus();
if (_clientSocket != null) if (_clientSocket != null)
{ {
_clientSocket.Close(); _clientSocket.Close();
_clientSocket = null; _clientSocket = null;
} }
log.info("客户端关闭");
} }
/// <summary> /// <summary>
...@@ -142,7 +139,7 @@ namespace Agv ...@@ -142,7 +139,7 @@ namespace Agv
}; };
_node.Add(node); _node.Add(node);
_nodeNoneState.Add(new Node { Name=nodeName}); _nodeNoneState.Add(new Node { Name=nodeName});
log.info("SetStatus " + node.ToText()); log.info(string.Format("SetStatus To Server[{0}]:[{1}]", ServerInfo, node.ToText()));
} }
else else
{ {
...@@ -152,26 +149,7 @@ namespace Agv ...@@ -152,26 +149,7 @@ namespace Agv
_node[index].Shelf = shelf; _node[index].Shelf = shelf;
_node[index].Type = type; _node[index].Type = type;
_node[index].Mark = mark; _node[index].Mark = mark;
log.info("SetStatus " + _node[index].ToText()); log.info(string.Format("SetStatus To Server[{0}]:[{1}]", ServerInfo, _node[index].ToText()));
}
}
/// <summary>
/// 设置状态
/// </summary>
/// <param name="nodeName">节点名称</param>
/// <param name="action">动作</param>
public void SetStatus(string nodeName, ClientAction action)
{
int index = _node.FindIndex(s => s.Name == nodeName);
if (index == -1) //没有找到
{
log.info("SetStatus 没有找到" + nodeName);
}
else
{
_node[index].Action = action;
log.info("SetStatus " + _node[index].ToText());
} }
} }
...@@ -190,17 +168,16 @@ namespace Agv ...@@ -190,17 +168,16 @@ namespace Agv
if (IsConn) if (IsConn)
{ {
_countRecon = 0; _countRecon = 0;
log.info("连接服务器成功"); log.info(string.Format("连接到服务端[{0}]成功",ServerInfo));
Connected?.Invoke(IsConn); Connected?.Invoke(IsConn);
} }
else else
{ {
log.info("连接服务器失败" + ++_countRecon + "次"); log.warn("连接服务器失败" + ++_countRecon + "次");
} }
} }
Thread.Sleep(2000); Thread.Sleep(2000);
} }
log.info("Quit Thread Reconnect");
} }
/// <summary> /// <summary>
...@@ -250,7 +227,7 @@ namespace Agv ...@@ -250,7 +227,7 @@ namespace Agv
byte[] arrMsgRec = new byte[1024]; byte[] arrMsgRec = new byte[1024];
// 将接收到的数据存入到输入 arrMsgRec中; // 将接收到的数据存入到输入 arrMsgRec中;
int length = -1; int length = -1;
if (_clientSocket.Poll(-1, SelectMode.SelectRead)) if (_clientSocket!=null && _clientSocket.Poll(-1, SelectMode.SelectRead))
{ {
try try
{ {
...@@ -263,19 +240,11 @@ namespace Agv ...@@ -263,19 +240,11 @@ namespace Agv
break; break;
} }
} }
catch (SocketException se) catch (ObjectDisposedException ode)
{
IsConn = false;
Connected?.Invoke(IsConn);
log.error(string.Format("客户端[{0}]接收服务端[{1}]的消息出现异常", _clientSocket.RemoteEndPoint.ToString(), ServerInfo), se);
break;
}
catch (Exception e)
{ {
IsConn = false; IsConn = false;
Connected?.Invoke(IsConn); Connected?.Invoke(IsConn);
log.error(string.Format("客户端[{0}]接收服务端[{1}]的消息出现异常", _clientSocket.RemoteEndPoint.ToString(), ServerInfo), e); log.info(string.Format("客户端已关闭"));
break;
} }
} }
...@@ -283,36 +252,14 @@ namespace Agv ...@@ -283,36 +252,14 @@ namespace Agv
{ {
byte[] buff = new byte[length]; byte[] buff = new byte[length];
Array.Copy(arrMsgRec, 0, buff, 0, length); Array.Copy(arrMsgRec, 0, buff, 0, length);
StickyBagHandle(buff);
Node node = Common.Decode(buff);
if (node == null)
{
log.error("命令解析失败");
}
else
{
log.info("触发Received事件," + node.ToText());
Received?.Invoke(node);
}
} }
}
//if (_clientSocket.Available > 0) catch (SocketException se)
//{ {
// int count = _clientSocket.Receive(temp); IsConn = false;
// byte[] buff = new byte[count]; Connected?.Invoke(IsConn);
// Array.Copy(temp, 0, buff, 0, count); log.error(string.Format("客户端接收服务端[{0}]的消息出现异常", ServerInfo), se);
// Node node = Common.Decode(buff);
// if (node == null)
// {
// LogUtil.error("命令解析失败");
// }
// else
// {
// LogUtil.info("触发Received事件," + node.ToText());
// Received?.Invoke(node);
// }
//}
} }
catch (Exception ex) catch (Exception ex)
{ {
...@@ -322,65 +269,168 @@ namespace Agv ...@@ -322,65 +269,168 @@ namespace Agv
} }
} }
} }
}
#region 粘包处理
byte[] surplusBuffer = null;//不完整的数据包,即用户自定义缓冲区
/// <summary>
/// 粘包处理
/// </summary>
/// <param name="bytes"></param>
private void StickyBagHandle(byte[] bytes)
{
//bytes 为系统缓冲区数据
//bytesRead为系统缓冲区长度
int bytesRead = bytes.Length;
if (bytesRead > 0)
{
if (surplusBuffer !=null)
{
byte[] curBuffer = surplusBuffer.Concat(bytes).ToArray();//拼接上一次剩余的包
//更新会话的最新字节
surplusBuffer = curBuffer;//同步
}
else
{
if (Common.CheckHeadChar(bytes, out int startIdx))//检查是否存在指定包头识别字符
{
//添加会话ID的bytes
byte[] tmp = new byte[bytesRead - startIdx];
Buffer.BlockCopy(bytes, startIdx, tmp, 0, bytesRead - startIdx);
surplusBuffer = tmp;//同步
}
else
return;
}
log.info("Quit Thread ListenNet"); //已经完成读取每个数据包长度
} int haveRead = 0;
//这里totalLen的长度有可能大于缓冲区大小的(因为 这里的surplusBuffer 是系统缓冲区+不完整的数据包)
int totalLen = surplusBuffer.Length;
while (haveRead <= totalLen)
{
//如果在N次拆解后剩余的数据包连一个包头的长度都不够
//说明是上次读取N个完整数据包后,剩下的最后一个非完整的数据包
if (totalLen - haveRead < Common.headSize)
{
byte[] byteSub = new byte[totalLen - haveRead];
//把剩下不够一个完整的数据包存起来
Buffer.BlockCopy(surplusBuffer, haveRead, byteSub, 0, totalLen - haveRead);
surplusBuffer = byteSub;
totalLen = 0;
break;
}
//如果够了一个完整包,则读取包头的数据
byte[] headByte = new byte[Common.headSize];
Buffer.BlockCopy(surplusBuffer, haveRead, headByte, 0, Common.headSize);//从缓冲区里读取包头的字节
//判断包头起始符
int bodySize = BitConverter.ToUInt16(headByte, 2);//从包头里面分析出包体的长度
//这里的 haveRead=等于N个数据包的长度 从0开始;0,1,2,3....N
//如果自定义缓冲区拆解N个包后的长度 大于 总长度,说最后一段数据不够一个完整的包了,拆出来保存
if (haveRead + Common.headSize + bodySize > totalLen)
{
byte[] byteSub = new byte[totalLen - haveRead];
Buffer.BlockCopy(surplusBuffer, haveRead, byteSub, 0, totalLen - haveRead);
surplusBuffer = byteSub;
break;
}
else
{
//挨个分解每个包,解析成实际文字
//String strc = Encoding.UTF8.GetString(surplusBuffer, haveRead + headSize, bodySize);
byte[] resBytes = new byte[bodySize];
Buffer.BlockCopy(surplusBuffer, haveRead + Common.headSize, resBytes, 0, bodySize);
log.debug(string.Format("[Receive data from Server[{0}]: {1}", ServerInfo, Common.HexBuff(resBytes)));
DecodeNode(resBytes);
//依次累加当前的数据包的长度
haveRead = haveRead + Common.headSize + bodySize;
if (Common.headSize + bodySize == bytesRead)//如果当前接收的数据包长度正好等于缓冲区长度,则待拼接的不规则数据长度归0
{
surplusBuffer = null;//设置空 回到原始状态
totalLen = 0;//清0
}
}
}
}
}
#endregion
private void DecodeNode(byte[] resultBytes)
{
Node node = Common.Decode(resultBytes);
if (node == null)
{
log.error("命令解析失败");
}
else
{
log.info(string.Format("Received事件触发:{0}", node.ToText()));
Received?.Invoke(node);
}
}
/// <summary> /// <summary>
/// 连续发送状态线程 /// 连续发送状态线程
/// </summary> /// </summary>
private void KeepSendStatus() private void KeepSendStatus()
{ {
bool bln;
while (_loopClient) while (_loopClient)
{ {
Thread.Sleep(SendSleep * 1000); Thread.Sleep(SendSleep * 1000);
if (!IsConn) continue; if (!IsConn) continue;
if (_clientSocket == null) continue; if (_clientSocket == null) continue;
if (_IsEecodeSingleNode) SendStatus();
{
for (int i = 0; i < _node.Count; i++) }
{ }
if (!_loopClient) break;
Thread.Sleep(500); private void SendStatus()
if (!CancelState) {
{ bool bln;
byte[] buff = Common.Encode(_node[i]); if (Common.EnDecodeSingleNode)
bln = Send(buff); {
} for (int i = 0; i < _node.Count; i++)
else
{
Node nostate = _node[i].ToCopy();
nostate.Action = ClientAction.None;
byte[] buff = Common.Encode(nostate);
bln = Send(buff);
}
if (!bln) continue;
}
}
else
{ {
if (_node.Count == 0) continue; Thread.Sleep(100);
if (!CancelState) if (!CancelState)
{ {
byte[] buff = Common.Encode(_node); byte[] buff = Common.Encode(_node[i]);
if (!_loopClient) break;
bln = Send(buff); bln = Send(buff);
} }
else else
{ {
byte[] buff = Common.Encode(_nodeNoneState); Node nostate = _node[i].ToCopy();
if (!_loopClient) break; nostate.Action = ClientAction.None;
byte[] buff = Common.Encode(nostate);
bln = Send(buff); bln = Send(buff);
} }
if (!bln) continue;
}
}
else
{
if (_node.Count == 0) return;
if (!CancelState)
{
byte[] buff = Common.Encode(_node);
bln = Send(buff);
}
else
{
byte[] buff = Common.Encode(_nodeNoneState);
bln = Send(buff);
} }
} }
log.info("Quit Thread SendStatus");
} }
/// <summary> /// <summary>
/// 发送命令 /// 发送命令
/// </summary> /// </summary>
...@@ -396,10 +446,9 @@ namespace Agv ...@@ -396,10 +446,9 @@ namespace Agv
try try
{ {
if (!_loopRecon) return false;
if (buff == null) return false; if (buff == null) return false;
_clientSocket.Send(buff); _clientSocket.Send(buff);
log.debug(string.Format("Send to Server:{0}", string.Join(" ", buff))); log.debug(string.Format("Send to Server:{0}", Common.HexBuff(buff)));
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
...@@ -436,7 +485,7 @@ namespace Agv ...@@ -436,7 +485,7 @@ namespace Agv
ping.Dispose(); ping.Dispose();
if (result.Status != System.Net.NetworkInformation.IPStatus.Success) if (result.Status != System.Net.NetworkInformation.IPStatus.Success)
{ {
log.info("Ping " + ip + " 请求没有响应"); log.warn("Ping " + ip + " 请求没有响应");
return false; return false;
} }
return true; return true;
......
...@@ -35,9 +35,6 @@ ...@@ -35,9 +35,6 @@
<LangVersion>8.0</LangVersion> <LangVersion>8.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="log4net">
<HintPath>..\..\..\..\DLL\log4net.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Web.Extensions" /> <Reference Include="System.Web.Extensions" />
......
此文件的差异太大,无法显示。
b85b5ff4afa439da48046bd004c84f66501d0684 7d5e8676cee1b0e36ad2454791cf299bb510c5f0
...@@ -2,7 +2,9 @@ E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\Agv.Client.dll ...@@ -2,7 +2,9 @@ E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\Agv.Client.dll
E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\Agv.Client.pdb E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\Agv.Client.pdb
E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\Agv.dll E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\Agv.dll
E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\Newtonsoft.Json.dll E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\Newtonsoft.Json.dll
E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\log4net.dll
E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\Agv.pdb E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\Agv.pdb
E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\bin\Debug\log4net.xml
E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\obj\Debug\Client.csprojAssemblyReference.cache E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\obj\Debug\Client.csprojAssemblyReference.cache
E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\obj\Debug\Client.csproj.CoreCompileInputs.cache E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\obj\Debug\Client.csproj.CoreCompileInputs.cache
E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\obj\Debug\Client.csproj.CopyComplete E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\obj\Debug\Client.csproj.CopyComplete
......
...@@ -34,11 +34,13 @@ ...@@ -34,11 +34,13 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="log4net"> <Reference Include="log4net, Version=2.0.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\..\DLL\log4net.dll</HintPath> <HintPath>..\packages\log4net.2.0.12\lib\net45\log4net.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
...@@ -71,6 +73,7 @@ ...@@ -71,6 +73,7 @@
<DependentUpon>Resources.resx</DependentUpon> <DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
</Compile> </Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings"> <None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator> <Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput> <LastGenOutput>Settings.Designer.cs</LastGenOutput>
......
...@@ -7,19 +7,19 @@ ...@@ -7,19 +7,19 @@
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup> </startup>
<log4net> <log4net>
<appender name="AgvClient" type="log4net.Appender.RollingFileAppender"> <appender name="Agv" type="log4net.Appender.RollingFileAppender">
<file value="logs/AgvClient.log"/> <file value="logs/Agv.log"/>
<param name="Encoding" value="UTF-8"/> <param name="Encoding" value="UTF-8"/>
<appendToFile value="true"/> <appendToFile value="true"/>
<rollingStyle value="Date"/> <rollingStyle value="Date"/>
<datePattern value="yyyy-MM-dd"/> <datePattern value="yyyy-MM-dd"/>
<layout type="log4net.Layout.PatternLayout"> <layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%date][%t]%-5p %m%n"/> <conversionPattern value="[%date][%t][%c:%L]%-5p %m%n"/>
</layout> </layout>
</appender> </appender>
<root> <root>
<level value="debug"/> <level value="Info"/>
<appender-ref ref="AgvClient"/> <appender-ref ref="Agv"/>
</root> </root>
</log4net> </log4net>
</configuration> </configuration>
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
this.comboBox2 = new System.Windows.Forms.ComboBox(); this.comboBox2 = new System.Windows.Forms.ComboBox();
this.comboBox3 = new System.Windows.Forms.ComboBox(); this.comboBox3 = new System.Windows.Forms.ComboBox();
this.comboBox4 = new System.Windows.Forms.ComboBox(); this.comboBox4 = new System.Windows.Forms.ComboBox();
this.label8 = new System.Windows.Forms.Label();
this.textBox4 = new System.Windows.Forms.TextBox(); this.textBox4 = new System.Windows.Forms.TextBox();
this.label9 = new System.Windows.Forms.Label(); this.label9 = new System.Windows.Forms.Label();
this.label10 = new System.Windows.Forms.Label(); this.label10 = new System.Windows.Forms.Label();
...@@ -53,10 +52,17 @@ ...@@ -53,10 +52,17 @@
this.button4 = new System.Windows.Forms.Button(); this.button4 = new System.Windows.Forms.Button();
this.button5 = new System.Windows.Forms.Button(); this.button5 = new System.Windows.Forms.Button();
this.label11 = new System.Windows.Forms.Label(); this.label11 = new System.Windows.Forms.Label();
this.label12 = new System.Windows.Forms.Label();
this.button6 = new System.Windows.Forms.Button(); this.button6 = new System.Windows.Forms.Button();
this.label13 = new System.Windows.Forms.Label(); this.label13 = new System.Windows.Forms.Label();
this.button7 = new System.Windows.Forms.Button(); this.button7 = new System.Windows.Forms.Button();
this.textBox6 = new System.Windows.Forms.TextBox();
this.button8 = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.listBox1 = new System.Windows.Forms.ListBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.listBox2 = new System.Windows.Forms.ListBox();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// //
// button1 // button1
...@@ -190,15 +196,6 @@ ...@@ -190,15 +196,6 @@
this.comboBox4.Size = new System.Drawing.Size(121, 20); this.comboBox4.Size = new System.Drawing.Size(121, 20);
this.comboBox4.TabIndex = 14; this.comboBox4.TabIndex = 14;
// //
// label8
//
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(77, 240);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(41, 12);
this.label8.TabIndex = 15;
this.label8.Text = "label8";
//
// textBox4 // textBox4
// //
this.textBox4.Location = new System.Drawing.Point(365, 12); this.textBox4.Location = new System.Drawing.Point(365, 12);
...@@ -231,13 +228,13 @@ ...@@ -231,13 +228,13 @@
this.textBox5.Name = "textBox5"; this.textBox5.Name = "textBox5";
this.textBox5.Size = new System.Drawing.Size(100, 21); this.textBox5.Size = new System.Drawing.Size(100, 21);
this.textBox5.TabIndex = 19; this.textBox5.TabIndex = 19;
this.textBox5.Text = "12000"; this.textBox5.Text = "9501";
// //
// button2 // button2
// //
this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button2.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); this.button2.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button2.Location = new System.Drawing.Point(314, 77); this.button2.Location = new System.Drawing.Point(12, 235);
this.button2.Name = "button2"; this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(138, 38); this.button2.Size = new System.Drawing.Size(138, 38);
this.button2.TabIndex = 20; this.button2.TabIndex = 20;
...@@ -249,7 +246,7 @@ ...@@ -249,7 +246,7 @@
// //
this.button3.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.button3.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button3.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); this.button3.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button3.Location = new System.Drawing.Point(314, 180); this.button3.Location = new System.Drawing.Point(348, 235);
this.button3.Name = "button3"; this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(138, 38); this.button3.Size = new System.Drawing.Size(138, 38);
this.button3.TabIndex = 21; this.button3.TabIndex = 21;
...@@ -284,26 +281,17 @@ ...@@ -284,26 +281,17 @@
// label11 // label11
// //
this.label11.AutoSize = true; this.label11.AutoSize = true;
this.label11.Location = new System.Drawing.Point(482, 93); this.label11.Location = new System.Drawing.Point(515, 251);
this.label11.Name = "label11"; this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(65, 12); this.label11.Size = new System.Drawing.Size(65, 12);
this.label11.TabIndex = 24; this.label11.TabIndex = 24;
this.label11.Text = "服务端状态"; this.label11.Text = "服务端状态";
// //
// label12
//
this.label12.AutoSize = true;
this.label12.Location = new System.Drawing.Point(77, 269);
this.label12.Name = "label12";
this.label12.Size = new System.Drawing.Size(47, 12);
this.label12.TabIndex = 25;
this.label12.Text = "label12";
//
// button6 // button6
// //
this.button6.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.button6.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button6.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); this.button6.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button6.Location = new System.Drawing.Point(314, 128); this.button6.Location = new System.Drawing.Point(177, 235);
this.button6.Name = "button6"; this.button6.Name = "button6";
this.button6.Size = new System.Drawing.Size(138, 38); this.button6.Size = new System.Drawing.Size(138, 38);
this.button6.TabIndex = 26; this.button6.TabIndex = 26;
...@@ -314,7 +302,7 @@ ...@@ -314,7 +302,7 @@
// label13 // label13
// //
this.label13.AutoSize = true; this.label13.AutoSize = true;
this.label13.Location = new System.Drawing.Point(472, 198); this.label13.Location = new System.Drawing.Point(452, 128);
this.label13.Name = "label13"; this.label13.Name = "label13";
this.label13.Size = new System.Drawing.Size(89, 12); this.label13.Size = new System.Drawing.Size(89, 12);
this.label13.TabIndex = 27; this.label13.TabIndex = 27;
...@@ -333,15 +321,78 @@ ...@@ -333,15 +321,78 @@
this.button7.UseVisualStyleBackColor = false; this.button7.UseVisualStyleBackColor = false;
this.button7.Click += new System.EventHandler(this.button7_Click); this.button7.Click += new System.EventHandler(this.button7_Click);
// //
// textBox6
//
this.textBox6.Location = new System.Drawing.Point(804, 90);
this.textBox6.Multiline = true;
this.textBox6.Name = "textBox6";
this.textBox6.Size = new System.Drawing.Size(555, 193);
this.textBox6.TabIndex = 30;
//
// button8
//
this.button8.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button8.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button8.Location = new System.Drawing.Point(992, 26);
this.button8.Name = "button8";
this.button8.Size = new System.Drawing.Size(150, 38);
this.button8.TabIndex = 31;
this.button8.Text = "生成字节码";
this.button8.UseVisualStyleBackColor = true;
this.button8.Click += new System.EventHandler(this.button8_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.listBox1);
this.groupBox1.Location = new System.Drawing.Point(24, 306);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(636, 198);
this.groupBox1.TabIndex = 33;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "从客户端接收的数据";
//
// listBox1
//
this.listBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.listBox1.FormattingEnabled = true;
this.listBox1.ItemHeight = 12;
this.listBox1.Location = new System.Drawing.Point(3, 17);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(630, 178);
this.listBox1.TabIndex = 0;
//
// groupBox2
//
this.groupBox2.Controls.Add(this.listBox2);
this.groupBox2.Location = new System.Drawing.Point(703, 306);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(689, 198);
this.groupBox2.TabIndex = 34;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "从服务端接收的数据";
//
// listBox2
//
this.listBox2.Dock = System.Windows.Forms.DockStyle.Fill;
this.listBox2.FormattingEnabled = true;
this.listBox2.ItemHeight = 12;
this.listBox2.Location = new System.Drawing.Point(3, 17);
this.listBox2.Name = "listBox2";
this.listBox2.Size = new System.Drawing.Size(683, 178);
this.listBox2.TabIndex = 1;
//
// Form1 // Form1
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(772, 310); this.ClientSize = new System.Drawing.Size(1415, 633);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.button8);
this.Controls.Add(this.textBox6);
this.Controls.Add(this.button7); this.Controls.Add(this.button7);
this.Controls.Add(this.label13); this.Controls.Add(this.label13);
this.Controls.Add(this.button6); this.Controls.Add(this.button6);
this.Controls.Add(this.label12);
this.Controls.Add(this.label11); this.Controls.Add(this.label11);
this.Controls.Add(this.button5); this.Controls.Add(this.button5);
this.Controls.Add(this.button4); this.Controls.Add(this.button4);
...@@ -351,7 +402,6 @@ ...@@ -351,7 +402,6 @@
this.Controls.Add(this.label10); this.Controls.Add(this.label10);
this.Controls.Add(this.label9); this.Controls.Add(this.label9);
this.Controls.Add(this.textBox4); this.Controls.Add(this.textBox4);
this.Controls.Add(this.label8);
this.Controls.Add(this.comboBox4); this.Controls.Add(this.comboBox4);
this.Controls.Add(this.comboBox3); this.Controls.Add(this.comboBox3);
this.Controls.Add(this.comboBox2); this.Controls.Add(this.comboBox2);
...@@ -373,7 +423,10 @@ ...@@ -373,7 +423,10 @@
this.ShowIcon = false; this.ShowIcon = false;
this.Text = "agv对接模拟客户端"; this.Text = "agv对接模拟客户端";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed);
this.Load += new System.EventHandler(this.Form1_Load); this.Load += new System.EventHandler(this.Form1_Load);
this.groupBox1.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
...@@ -396,7 +449,6 @@ ...@@ -396,7 +449,6 @@
private System.Windows.Forms.ComboBox comboBox2; private System.Windows.Forms.ComboBox comboBox2;
private System.Windows.Forms.ComboBox comboBox3; private System.Windows.Forms.ComboBox comboBox3;
private System.Windows.Forms.ComboBox comboBox4; private System.Windows.Forms.ComboBox comboBox4;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.TextBox textBox4; private System.Windows.Forms.TextBox textBox4;
private System.Windows.Forms.Label label9; private System.Windows.Forms.Label label9;
private System.Windows.Forms.Label label10; private System.Windows.Forms.Label label10;
...@@ -406,10 +458,15 @@ ...@@ -406,10 +458,15 @@
private System.Windows.Forms.Button button4; private System.Windows.Forms.Button button4;
private System.Windows.Forms.Button button5; private System.Windows.Forms.Button button5;
private System.Windows.Forms.Label label11; private System.Windows.Forms.Label label11;
private System.Windows.Forms.Label label12;
private System.Windows.Forms.Button button6; private System.Windows.Forms.Button button6;
private System.Windows.Forms.Label label13; private System.Windows.Forms.Label label13;
private System.Windows.Forms.Button button7; private System.Windows.Forms.Button button7;
private System.Windows.Forms.TextBox textBox6;
private System.Windows.Forms.Button button8;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.ListBox listBox2;
} }
} }
...@@ -21,6 +21,7 @@ namespace AgvClientTest ...@@ -21,6 +21,7 @@ namespace AgvClientTest
private void Form1_Load(object sender, EventArgs e) private void Form1_Load(object sender, EventArgs e)
{ {
Agv.Common.EnDecodeSingleNode = false;
server = new Agv.Server(); server = new Agv.Server();
server.NodeChanged += Server_NodeChanged; server.NodeChanged += Server_NodeChanged;
server.NodeOnline += Server_NodeOnline; server.NodeOnline += Server_NodeOnline;
...@@ -37,39 +38,32 @@ namespace AgvClientTest ...@@ -37,39 +38,32 @@ namespace AgvClientTest
client.Connected += Client_Connected; client.Connected += Client_Connected;
} }
private void Client_Log(string s)
{
Agv.log.info(s);
}
private void Server_NodeChanged(Agv.Node clientNode) private void Server_NodeChanged(Agv.Node clientNode)
{ {
this.Invoke(new Action(() => this.Invoke(new Action(() =>
{ {
label8.Text = "从客户端接收:" + clientNode.ToText(); listBox1.Items.Add(clientNode.ToText());
listBox1.SelectedIndex = listBox1.Items.Count - 1;
} }
)); ));
} }
private void Form1_FormClosing(object sender, FormClosingEventArgs e) private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{ {
try
{
if (server != null)
{
server.NodeChanged -= Server_NodeChanged;
server.NodeOnline -= Server_NodeOnline;
server.Stop();
server = null;
}
if (client != null)
{
client.Received -= Client_Received;
client.Connected -= Client_Connected;
client.Close();
client = null;
}
}
catch { }
} }
private void button1_Click(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e)
{ {
//comboBox1.Items.AddRange(Enum.GetNames(typeof(Agv.ClientAction)));
//comboBox2.Items.AddRange(Enum.GetNames(typeof(Agv.ClientLevel)));
//comboBox3.Items.AddRange(Enum.GetNames(typeof(Agv.ClientType)));
//comboBox4.Items.AddRange(Enum.GetNames(typeof(Agv.ClientShelf)));
int i1 = comboBox1.SelectedIndex; int i1 = comboBox1.SelectedIndex;
int i2 = comboBox2.SelectedIndex; int i2 = comboBox2.SelectedIndex;
int i3 = comboBox4.SelectedIndex; int i3 = comboBox4.SelectedIndex;
...@@ -80,7 +74,11 @@ namespace AgvClientTest ...@@ -80,7 +74,11 @@ namespace AgvClientTest
//client.SetStatus(textBox1.Text,textBox3.Text,textBox2.Text, (Agv.ClientAction)i1, //client.SetStatus(textBox1.Text,textBox3.Text,textBox2.Text, (Agv.ClientAction)i1,
// (Agv.ClientLevel)i2,(Agv.ClientShelf)i3, // (Agv.ClientLevel)i2,(Agv.ClientShelf)i3,
// (Agv.ClientType)i4); // (Agv.ClientType)i4);
client.SetStatus(textBox1.Text, textBox3.Text, textBox2.Text, (Agv.ClientAction)i1, (Agv.ClientLevel)i2, (Agv.ClientShelf)i3); client.SetStatus(textBox1.Text, textBox3.Text, textBox2.Text, (Agv.ClientAction)i1, (Agv.ClientLevel)i2, (Agv.ClientShelf)i3, (Agv.ClientType)i4);//, (Agv.ClientShelf)i3
//for (int i = 0; i < 100; i++)
//{
// client.SetStatus(string.Format("A{0}",i), textBox3.Text, textBox2.Text, (Agv.ClientAction)i1, (Agv.ClientLevel)i2, (Agv.ClientShelf)i3, (Agv.ClientType)i4);
//}
})); }));
task.Start(); task.Start();
...@@ -123,7 +121,6 @@ namespace AgvClientTest ...@@ -123,7 +121,6 @@ namespace AgvClientTest
private void button4_Click(object sender, EventArgs e) private void button4_Click(object sender, EventArgs e)
{ {
client.Connect(textBox4.Text, int.Parse(textBox5.Text)); client.Connect(textBox4.Text, int.Parse(textBox5.Text));
} }
...@@ -131,6 +128,8 @@ namespace AgvClientTest ...@@ -131,6 +128,8 @@ namespace AgvClientTest
{ {
this.Invoke(new Action(() => this.Invoke(new Action(() =>
{ {
if (label3 == null)
return;
if (!status) if (!status)
label13.BackColor = Color.Red; label13.BackColor = Color.Red;
else else
...@@ -143,7 +142,8 @@ namespace AgvClientTest ...@@ -143,7 +142,8 @@ namespace AgvClientTest
{ {
this.Invoke(new Action(() => this.Invoke(new Action(() =>
{ {
label12.Text = "从服务端端接收:" + node.ToText(); listBox2.Items.Add(node.ToText());
listBox2.SelectedIndex = listBox2.Items.Count - 1;
} }
)); ));
} }
...@@ -173,5 +173,55 @@ namespace AgvClientTest ...@@ -173,5 +173,55 @@ namespace AgvClientTest
} }
} }
private void button8_Click(object sender, EventArgs e)
{
textBox6.Text = "";
try
{
int i1 = comboBox1.SelectedIndex;
int i2 = comboBox2.SelectedIndex;
int i3 = comboBox4.SelectedIndex;
int i4 = comboBox3.SelectedIndex;
Agv.Node node = new Agv.Node()
{
Name = textBox1.Text,
Mark = textBox3.Text,
RFID = textBox2.Text,
Action = (Agv.ClientAction)i1,
Level = (Agv.ClientLevel)i2,
Shelf = (Agv.ClientShelf)i3,
Type = (Agv.ClientType)i4
};
byte[] buff = Agv.Common.Encode(node);
textBox6.Text = Agv.Common.HexBuffWithoutSpace(buff);
}
catch
{
textBox6.Text = "";
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
//try
//{
// if (server != null)
// {
// server.NodeChanged -= Server_NodeChanged;
// server.NodeOnline -= Server_NodeOnline;
// server.Stop();
// server = null;
// }
// if (client != null)
// {
// client.Received -= Client_Received;
// client.Connected -= Client_Connected;
// client.Close();
// client = null;
// }
//}
//catch { }
}
} }
} }
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
<log4net>
<appender name="Agv" type="log4net.Appender.RollingFileAppender">
<file value="logs/Agv.log"/>
<param name="Encoding" value="UTF-8"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<datePattern value="yyyy-MM-dd"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%date][%t][%c:%L]%-5p %m%n"/>
</layout>
</appender>
<root>
<level value="Info"/>
<appender-ref ref="Agv"/>
</root>
</log4net>
</configuration>
此文件的差异太大,无法显示。

\ No newline at end of file \ No newline at end of file
...@@ -7,19 +7,19 @@ ...@@ -7,19 +7,19 @@
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup> </startup>
<log4net> <log4net>
<appender name="AgvClient" type="log4net.Appender.RollingFileAppender"> <appender name="Agv" type="log4net.Appender.RollingFileAppender">
<file value="logs/AgvClient.log"/> <file value="logs/Agv.log"/>
<param name="Encoding" value="UTF-8"/> <param name="Encoding" value="UTF-8"/>
<appendToFile value="true"/> <appendToFile value="true"/>
<rollingStyle value="Date"/> <rollingStyle value="Date"/>
<datePattern value="yyyy-MM-dd"/> <datePattern value="yyyy-MM-dd"/>
<layout type="log4net.Layout.PatternLayout"> <layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%date][%t]%-5p %m%n"/> <conversionPattern value="[%date][%t][%c:%L]%-5p %m%n"/>
</layout> </layout>
</appender> </appender>
<root> <root>
<level value="debug"/> <level value="Info"/>
<appender-ref ref="AgvClient"/> <appender-ref ref="Agv"/>
</root> </root>
</log4net> </log4net>
</configuration> </configuration>
此文件的差异太大,无法显示。
[2021-04-26 16:46:04,148][5][Agv.log:19]INFO 连接到服务端[127.0.0.1:9501]成功
[2021-04-26 16:46:06,201][6][Agv.log:19]INFO SetStatus To Server[127.0.0.1:9501]:[Name=A1,RFID=D1,Mark=2-1A,cut,Action=None,Level=Low,Type=None,Shelf=None]
[2021-04-26 16:46:11,167][3][Agv.log:19]INFO 客户端已关闭
[2021-04-25 16:17:43,243][6][Agv.log:19]INFO SetStatus To Server[192.168.101.20:9501]:[Name=A1,RFID=D1,Mark=2-1A,cut,Action=None,Level=Low,Type=None,Shelf=None]
[2021-04-25 16:17:52,629][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:17:52,636][5][Agv.log:32]WARN 连接服务器失败1次
[2021-04-25 16:18:15,697][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:18:15,697][5][Agv.log:32]WARN 连接服务器失败2次
[2021-04-25 16:18:38,769][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:18:38,769][5][Agv.log:32]WARN 连接服务器失败3次
[2021-04-25 16:19:01,841][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:19:01,842][5][Agv.log:32]WARN 连接服务器失败4次
[2021-04-25 16:19:24,908][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:19:24,909][5][Agv.log:32]WARN 连接服务器失败5次
[2021-04-25 16:19:48,001][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:19:48,001][5][Agv.log:32]WARN 连接服务器失败6次
[2021-04-25 16:20:11,065][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:20:11,065][5][Agv.log:32]WARN 连接服务器失败7次
[2021-04-25 16:20:34,147][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:20:34,147][5][Agv.log:32]WARN 连接服务器失败8次
[2021-04-25 16:20:57,206][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:20:57,207][5][Agv.log:32]WARN 连接服务器失败9次
[2021-04-25 16:21:20,295][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:21:20,295][5][Agv.log:32]WARN 连接服务器失败10次
[2021-04-25 16:21:43,363][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:21:43,363][5][Agv.log:32]WARN 连接服务器失败11次
[2021-04-25 16:22:06,428][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:22:06,428][5][Agv.log:32]WARN 连接服务器失败12次
[2021-04-25 16:22:29,483][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:22:29,483][5][Agv.log:32]WARN 连接服务器失败13次
[2021-04-25 16:22:46,551][5][Agv.log:19]INFO 连接到服务端[192.168.101.20:9501]成功
[2021-04-25 16:23:08,568][3][Agv.log:28]ERROR 客户端接收服务端[192.168.101.20:9501]的消息出现异常
System.Net.Sockets.SocketException (0x80004005): 远程主机强迫关闭了一个现有的连接。
在 System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
在 System.Net.Sockets.Socket.Receive(Byte[] buffer)
在 Agv.AgvClient.ListenServerNet() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 234
[2021-04-25 16:23:29,719][5][Agv.log:28]ERROR Open Error
System.Net.Sockets.SocketException (0x80004005): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 192.168.101.20:9501
在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
在 System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)
在 Agv.AgvClient.Open() 位置 E:\Neotel\Projects\Gitee\AGV-Com\AgvClient\AgvClient.cs:行号 196
[2021-04-25 16:23:29,719][5][Agv.log:32]WARN 连接服务器失败1次
[2021-04-25 16:23:46,794][5][Agv.log:19]INFO 连接到服务端[192.168.101.20:9501]成功
[2021-04-25 16:24:34,805][6][Agv.log:19]INFO SetStatus To Server[192.168.101.20:9501]:[Name=A1,RFID=D1,Mark=2-1A,cut,Action=NeedEnter,Level=Low,Type=None,Shelf=None]
[2021-04-25 17:01:48,923][1][Agv.log:19]INFO AGVServer服务启动
[2021-04-25 17:01:48,979][1][Agv.log:28]ERROR AGVServer服务启动
System.Net.Sockets.SocketException (0x80004005): 在其上下文中,该请求的地址无效。
在 System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
在 System.Net.Sockets.Socket.Bind(EndPoint localEP)
在 Agv.Server.Start(String ip, Int32 port) 位置 E:\Neotel\Projects\Gitee\AGV-Com\Server\AgvServer.cs:行号 59
[2021-04-25 17:02:16,513][1][Agv.log:19]INFO AGVServer服务启动
[2021-04-25 17:03:32,235][3][Agv.log:19]INFO 客户端[192.168.101.20:2556]连接服务端[192.168.101.22:9501]成功
[2021-04-25 17:04:09,586][3][Agv.log:19]INFO 客户端[192.168.101.22:19550]连接服务端[192.168.101.22:9501]成功
[2021-04-25 17:04:09,588][7][Agv.log:19]INFO 连接到服务端[192.168.101.22:9501]成功
此文件的差异太大,无法显示。
f0308ac44290cb39c7a1e5c49291c49b056787f6 6dc610c4077a2c876673a453687d9aecd2273b3b
...@@ -44,10 +44,12 @@ E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\AgvClientTest.pdb ...@@ -44,10 +44,12 @@ E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\AgvClientTest.pdb
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.Client.dll E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.Client.dll
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.dll E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.dll
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.Server.dll E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.Server.dll
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\log4net.dll
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Newtonsoft.Json.dll E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Newtonsoft.Json.dll
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.Client.pdb E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.Client.pdb
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.pdb E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.pdb
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.Server.pdb E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\Agv.Server.pdb
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\bin\Debug\log4net.xml
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\obj\Debug\AgvClientTest.csprojAssemblyReference.cache E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\obj\Debug\AgvClientTest.csprojAssemblyReference.cache
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\obj\Debug\AgvClientTest.Form1.resources E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\obj\Debug\AgvClientTest.Form1.resources
E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\obj\Debug\AgvClientTest.Properties.Resources.resources E:\Neotel\Projects\Gitee\AGV-Com\AgvClientTest\obj\Debug\AgvClientTest.Properties.Resources.resources
......
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.12" targetFramework="net472" />
</packages>
\ No newline at end of file \ No newline at end of file
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Agv
{
public class Server
{
private bool loop;
private Socket _server; //服务端
Dictionary<string, Client> dictClient = new Dictionary<string, Client>(); //所有客户端
private Thread tListenClient; //监听客户端连接
private Dictionary<string, bool> nodeOnline = new Dictionary<string, bool>();
public delegate void NodeChangedEvent(Node clientNode);
public delegate void NodeOnlineEvent(string nodeName, bool online);
public event NodeChangedEvent NodeChanged;
public event NodeOnlineEvent NodeOnline;
private string serverIp;
private int serverPort;
private Dictionary<string, Node> nodeMap = new Dictionary<string, Node>();
/// <summary>
///
/// </summary>
/// <param name="_IsdecodeSingleNode">解码方式,默认解码多个节点</param>
public Server()
{
}
/// <summary>
/// 服务端信息
/// </summary>
public string ServerInfo
{
get
{
return string.Format("{0}:{1}", serverIp, serverPort.ToString());
}
}
/// <summary>
/// 开启服务
/// </summary>
public void Start(string ip = "0.0.0.0", int port = 12000)
{
try
{
log.info("AGVServer服务启动");
serverIp = ip;
serverPort = port;
IPEndPoint localEP;
if (ip.Equals("0.0.0.0"))
localEP = new IPEndPoint(IPAddress.Any, serverPort);
else
localEP = new IPEndPoint(IPAddress.Parse(ip), serverPort);
_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_server.Bind(localEP);
_server.Listen(100);
loop = true;
//_client = new List<Client>();
tListenClient = new Thread(new ThreadStart(ListenClient));
tListenClient.Start();
}
catch (Exception ex)
{
log.error("AGVServer服务启动", ex);
}
}
/// <summary>
/// 停止服务
/// </summary>
public void Stop()
{
try
{
loop = false;
foreach (string c in dictClient.Keys)
{
try
{
dictClient[c].ListenNet.Abort();
}
catch (Exception ex)
{
log.error(string.Format("关闭连接客户端[{0}]线程失败", c), ex);
}
try
{
dictClient[c].Socket.Close();
}
catch (Exception ex)
{
log.error(string.Format("关闭连接客户端[{0}]Socket失败", c), ex);
}
}
if (dictClient.Count > 0) dictClient.Clear();
if (nodeMap.Count > 0)
nodeMap.Clear();
if (_server != null)
{
_server.Close();
_server.Dispose();
}
}
catch (Exception ex)
{
log.error("AGVServer服务关闭", ex);
}
}
/// <summary>
/// 向服务端发送命令
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool SendToClient(string nodeName, string RFID, ClientAction action)
{
string tar = "";
int n = 0;
do
{
tar = FindClient(nodeName);
if (tar.Equals(""))
{
log.error("没有找到" + nodeName);
Thread.Sleep(500);
n++;
}
else
{
n = 10;
}
} while (n < 4);
if (tar.Equals("")) return false;
Node node = new Node(nodeName, RFID, action);
log.info("SendTo " + nodeName + " RFID=" + RFID + " " + action);
byte[] buff = Common.Encode(node);
return Send(tar, buff);
}
/// <summary>
/// 小车到达
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool Arrive(string nodeName, string RFID = "")
{
string tar = "";
int n = 0;
do
{
tar = FindClient(nodeName);
if (tar.Equals(""))
{
log.error("Arrive: 没有找到" + nodeName);
Thread.Sleep(500);
n++;
}
else
{
n = 10;
}
} while (n < 4);
if (tar.Equals("")) return false;
Node node = new Node(nodeName, RFID, ClientAction.Arrive);
log.info("SendTo " + nodeName + " RFID=" + RFID + " " + ClientAction.Arrive);
byte[] buff = Common.Encode(node);
return Send(tar, buff);
}
/// <summary>
/// 小车已准备好
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool Ready(string nodeName, string RFID = "")
{
string tar = "";
int n = 0;
do
{
tar = FindClient(nodeName);
if (tar.Equals(""))
{
log.error("Ready: 没有找到" + nodeName);
Thread.Sleep(500);
n++;
}
else
{
n = 10;
}
} while (n < 4);
if (tar.Equals("")) return false;
Node node = new Node(nodeName, RFID, ClientAction.Ready);
log.info("SendTo " + nodeName + " RFID=" + RFID + " " + ClientAction.Ready);
byte[] buff = Common.Encode(node);
return Send(tar, buff);
}
/// <summary>
/// 关门
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool CloseDoor(string nodeName, string RFID = "")
{
string tar = "";
int n = 0;
do
{
tar = FindClient(nodeName);
if (tar.Equals(""))
{
log.debug("CloseDoor: 没有找到" + nodeName);
Thread.Sleep(500);
n++;
}
else
{
n = 10;
}
} while (n < 4);
if (tar.Equals("")) return false;
Node node = new Node(nodeName, RFID, ClientAction.CloseDoor);
log.info("SendTo " + nodeName + " RFID=" + RFID + " " + ClientAction.CloseDoor);
byte[] buff = Common.Encode(node);
return Send(tar, buff);
}
/// <summary>
/// 监听客户端连接
/// </summary>
private void ListenClient()
{
while (loop)
{
try
{
// 开始监听客户端连接请求,Accept方法会阻断当前的线程;
Socket sokConnection = _server.Accept(); // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字;
IPEndPoint endPoint = (IPEndPoint)sokConnection.RemoteEndPoint;
string ip = endPoint.Address.ToString();
int port = endPoint.Port;
if (dictClient.TryGetValue(ip, out Client client1))
{
Offline(client1);
log.debug(string.Format("断开"));
}
log.info(string.Format("客户端[{0}]连接服务端[{1}]成功", endPoint.ToString(), ServerInfo));
Thread thr = new Thread(ListenNet);
Client client = new Client(sokConnection, thr, ip, endPoint.ToString());
thr.IsBackground = true;
thr.Start(client);
dictClient.Add(ip, client);
}
catch (SocketException)
{
//关闭连接,退出阻塞Accept
}
catch (Exception ex)
{
log.error("ListenClient", ex);
}
}
}
#region 粘包处理
//线程安全的字典
ConcurrentDictionary<string, byte[]> dic = new ConcurrentDictionary<string, byte[]>();
/// <summary>
/// 处理客户端发来的数据
/// </summary>
/// <param name="obj">每个客户的会话ID</param>
/// <param name="bytes">缓冲区数据</param>
/// <returns></returns>
private void StickyBagHandle(Client client, byte[] bytes)
{
//bytes 为系统缓冲区数据
//bytesRead为系统缓冲区长度
int bytesRead = bytes.Length;
string endpoint = client.IP;
if (bytesRead > 0)
{
byte[] surplusBuffer = null;
if (dic.TryGetValue(endpoint, out surplusBuffer))
{
byte[] curBuffer = surplusBuffer.Concat(bytes).ToArray();//拼接上一次剩余的包
//更新会话ID 的最新字节
dic.TryUpdate(endpoint, curBuffer, surplusBuffer);
surplusBuffer = curBuffer;//同步
}
else
{
if (Common.CheckHeadChar(bytes, out int startIdx))//检查是否存在指定包头识别字符
{
//添加会话ID的bytes
byte[] tmp = new byte[bytesRead - startIdx];
Buffer.BlockCopy(bytes, startIdx, tmp, 0, bytesRead - startIdx);
dic.TryAdd(endpoint, tmp);
surplusBuffer = tmp;//同步
}
else
return;
}
//已经完成读取每个数据包长度
int haveRead = 0;
//这里totalLen的长度有可能大于缓冲区大小的(因为 这里的surplusBuffer 是系统缓冲区+不完整的数据包)
int totalLen = surplusBuffer.Length;
while (haveRead <= totalLen)
{
//如果在N次拆解后剩余的数据包连一个包头的长度都不够
//说明是上次读取N个完整数据包后,剩下的最后一个非完整的数据包
if (totalLen - haveRead < Common.headSize)
{
byte[] byteSub = new byte[totalLen - haveRead];
//把剩下不够一个完整的数据包存起来
Buffer.BlockCopy(surplusBuffer, haveRead, byteSub, 0, totalLen - haveRead);
dic.TryUpdate(endpoint, byteSub, surplusBuffer);
surplusBuffer = byteSub;
totalLen = 0;
break;
}
//如果够了一个完整包,则读取包头的数据
byte[] headByte = new byte[Common.headSize];
Buffer.BlockCopy(surplusBuffer, haveRead, headByte, 0, Common.headSize);//从缓冲区里读取包头的字节
//判断包头起始符
int bodySize = BitConverter.ToUInt16(headByte, 2);//从包头里面分析出包体的长度
//这里的 haveRead=等于N个数据包的长度 从0开始;0,1,2,3....N
//如果自定义缓冲区拆解N个包后的长度 大于 总长度,说最后一段数据不够一个完整的包了,拆出来保存
if (haveRead + Common.headSize + bodySize > totalLen)
{
byte[] byteSub = new byte[totalLen - haveRead];
Buffer.BlockCopy(surplusBuffer, haveRead, byteSub, 0, totalLen - haveRead);
dic.TryUpdate(endpoint, byteSub, surplusBuffer);
surplusBuffer = byteSub;
break;
}
else
{
//挨个分解每个包,解析成实际文字
//String strc = Encoding.UTF8.GetString(surplusBuffer, haveRead + headSize, bodySize);
byte[] resBytes = new byte[bodySize];
Buffer.BlockCopy(surplusBuffer, haveRead + Common.headSize, resBytes, 0, bodySize);
log.debug(string.Format("[Receive data from:{0}] -> {1}", endpoint, Common.HexBuff(resBytes)));
DecodeNode(client, resBytes);
//依次累加当前的数据包的长度
haveRead = haveRead + Common.headSize + bodySize;
if (Common.headSize + bodySize == bytesRead)//如果当前接收的数据包长度正好等于缓冲区长度,则待拼接的不规则数据长度归0
{
byte[] xbtye = null;
dic.TryRemove(endpoint, out xbtye);
surplusBuffer = null;//设置空 回到原始状态
totalLen = 0;//清0
}
}
}
}
}
#endregion
private void DecodeNode(Client client, byte[] resultBytes)
{
//解码单个节点
if (Common.EnDecodeSingleNode)
{
Node node = Common.Decode(resultBytes);
if (node == null)
{
log.error("命令解析失败: " + Common.HexBuff(resultBytes));
}
else
{
//CommonVar.LogUtil.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);
}
}
else
{
//解码多个节点
List<Node> nodes = Common.DecodeNodes(resultBytes);
if (nodes == null)
{
log.error("命令解析失败: " + Common.HexBuff(resultBytes));
}
else
{
int idx = -1;
foreach (var node in nodes)
{
idx = client.nodeName.FindIndex(s => s == node.Name);
if (idx == -1) client.nodeName.Add(node.Name);
}
UpdateNodes(nodes);
}
}
}
/// <summary>
/// 客户端数据接收
/// </summary>
/// <param name="obj">索引</param>
private void ListenNet(object obj)
{
Client client = obj as Client;
Socket sokClient = client.Socket;
while (client.Loop)
{
// Thread.Sleep(sleep);
try
{
// 定义一个缓存区;
byte[] arrMsgRec = new byte[1024];
// 将接收到的数据存入到输入 arrMsgRec中;
int length = -1;
if (!client.Loop) return;
if (sokClient != null && sokClient.Poll(-1, SelectMode.SelectRead))
{
length = sokClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
if (length == 0)//连接正常断开
{
Offline(client);
log.info(string.Format("客户端[{0}]断开与服务端[{1}]的连接", sokClient.RemoteEndPoint.ToString(), ServerInfo));
return;
}
}
if (length > 0)
{
byte[] buff = new byte[length];
Array.Copy(arrMsgRec, 0, buff, 0, length);
StickyBagHandle(client, buff);
}
}
catch (Exception e)
{
}
}
}
private string FindClient(string nodeName)
{
foreach (string item in dictClient.Keys)
{
if (dictClient[item].nodeName.Contains(nodeName))
return item;
}
return "";
}
private void UpdateNode(Node node)
{
if (!nodeOnline.Keys.Contains(node.Name))
{
nodeOnline.Add(node.Name, true);
NodeOnline?.Invoke(node.Name, true);
}
else if (nodeOnline[node.Name].Equals(false))
{
nodeOnline[node.Name] = true;
NodeOnline?.Invoke(node.Name, true);
}
if (!nodeMap.Keys.Contains(node.Name))
{
nodeMap.Add(node.Name, node);
NodeChanged?.Invoke(node);
log.info(string.Format("节点添加并状态更新[{0}]", node.ToText()));
}
else if (!nodeMap[node.Name].Equals(node))
{
nodeMap[node.Name] = node;
NodeChanged?.Invoke(node);
log.info(string.Format("节点状态更新[{0}]", node.ToText()));
}
}
private void UpdateNodes(List<Node> nodes)
{
foreach (var node in nodes)
{
UpdateNode(node);
}
}
private void Offline(Client client)
{
try
{
client.Loop = false;
dictClient.Remove(client.IP);
if (client.Socket != null)
{
client.Socket.Close();
client.Socket = null;
}
for (int i = 0; i < client.nodeName.Count; i++)
{
if (!nodeOnline.Keys.Contains(client.nodeName[i]))
{
nodeOnline.Add(client.nodeName[i], false);
NodeOnline?.Invoke(client.nodeName[i], false);
}
else if (nodeOnline[client.nodeName[i]].Equals(true))
{
nodeOnline[client.nodeName[i]] = false;
NodeOnline?.Invoke(client.nodeName[i], false);
}
if (nodeMap.ContainsKey(client.nodeName[i]))
nodeMap.Remove(client.nodeName[i]);
}
client.nodeName.Clear();
client.ListenNet.Abort();
log.info(string.Format("关闭对客户端[{0}]的监听线程", client.Endpoint));
}
catch (ThreadAbortException)
{
log.info(string.Format("关闭对客户端[{0}]的监听线程", client.Endpoint));
}
}
private void Offline(string clientKey)
{
if (!dictClient.Keys.Contains(clientKey))
return;
Client client = dictClient[clientKey];
client.Loop = false;
client.Socket.Close();
for (int i = 0; i < client.nodeName.Count; i++)
{
if (!nodeOnline.Keys.Contains(client.nodeName[i]))
{
nodeOnline.Add(client.nodeName[i], false);
NodeOnline?.Invoke(client.nodeName[i], false);
}
else if (nodeOnline[client.nodeName[i]].Equals(true))
{
nodeOnline[client.nodeName[i]] = false;
NodeOnline?.Invoke(client.nodeName[i], false);
}
}
client.nodeName.Clear();
client.ListenNet.Abort();
client.Socket = null;
dictClient.Remove(client.IP);
}
/// <summary>
/// 发送命令
/// </summary>
/// <param name="idx"></param>
/// <param name="buff"></param>
/// <returns></returns>
private bool Send(string clientKey, byte[] buff)
{
for (int i = 1; i <= 3; i++)
{
try
{
dictClient[clientKey].Socket.Send(buff);
log.debug(string.Format("服务端[{0}]向客户端[{1}]发送消息:[{2}]", ServerInfo, clientKey, Common.HexBuff(buff)));
return true;
}
catch (Exception ex)
{
log.error("发送失败" + i + "次:" + ex.Message);
}
Thread.Sleep(100);
}
Offline(clientKey);
return false;
}
private class Client
{
public bool Loop;
public string Endpoint;
public string IP;
public List<string> nodeName;
public Socket Socket;
public Thread ListenNet;
public Client(Socket socket, Thread thread, string ip, string Endpoint)
{
Socket = socket;
ListenNet = thread;
Loop = true;
IP = ip;
this.Endpoint = Endpoint;
nodeName = new List<string>();
}
}
}
/// <summary>
/// 客户端的节点
/// </summary>
public class ClientNode : Node
{
/// <summary>
/// 在线状态
/// </summary>
public bool Online { get; set; }
/// <summary>
/// 是否可调用
/// </summary>
public bool IsUse { set; get; }
public string AliceName { get; set; }
/// <summary>
/// 客户端的节点
/// </summary>
public ClientNode() : base()
{
}
public ClientNode(string nodeName, string rfid, ClientAction clientAction) : base(nodeName)
{
RFID = rfid;
Action = clientAction;
}
/// <summary>
/// 客户端节点
/// </summary>
/// <param name="name"></param>
/// <param name="ip"></param>
/// <param name="isUse"></param>
public ClientNode(string name, string aliceName, bool isUse, int priority = 0) : base(name)
{
AliceName = aliceName;
Online = false;
IsUse = isUse;
Priority = priority;
}
/// <summary>
/// 客户端节点
/// </summary>
/// <param name="name"></param>
/// <param name="rfid"></param>
/// <param name="action"></param>
/// <param name="level"></param>
public ClientNode(string name, string rfid = "", string mark = "", ClientAction action = ClientAction.None, Agv.ClientLevel level = Agv.ClientLevel.Low) : base(name)
{
RFID = rfid;
Mark = mark;
Level = level;
Action = action;
}
/// <summary>
/// 脱机
/// </summary>
public void Offline()
{
RFID = "";
Action = ClientAction.None;
Online = false;
}
}
}
此文件的差异太大,无法显示。
...@@ -4,6 +4,7 @@ E:\Neotel\Projects\Gitee\AGV-Com\Server\bin\Debug\Agv.dll ...@@ -4,6 +4,7 @@ E:\Neotel\Projects\Gitee\AGV-Com\Server\bin\Debug\Agv.dll
E:\Neotel\Projects\Gitee\AGV-Com\Server\bin\Debug\Newtonsoft.Json.dll E:\Neotel\Projects\Gitee\AGV-Com\Server\bin\Debug\Newtonsoft.Json.dll
E:\Neotel\Projects\Gitee\AGV-Com\Server\bin\Debug\log4net.dll E:\Neotel\Projects\Gitee\AGV-Com\Server\bin\Debug\log4net.dll
E:\Neotel\Projects\Gitee\AGV-Com\Server\bin\Debug\Agv.pdb E:\Neotel\Projects\Gitee\AGV-Com\Server\bin\Debug\Agv.pdb
E:\Neotel\Projects\Gitee\AGV-Com\Server\bin\Debug\log4net.xml
E:\Neotel\Projects\Gitee\AGV-Com\Server\obj\Debug\Server.csprojAssemblyReference.cache E:\Neotel\Projects\Gitee\AGV-Com\Server\obj\Debug\Server.csprojAssemblyReference.cache
E:\Neotel\Projects\Gitee\AGV-Com\Server\obj\Debug\Server.csproj.CoreCompileInputs.cache E:\Neotel\Projects\Gitee\AGV-Com\Server\obj\Debug\Server.csproj.CoreCompileInputs.cache
E:\Neotel\Projects\Gitee\AGV-Com\Server\obj\Debug\Server.csproj.CopyComplete E:\Neotel\Projects\Gitee\AGV-Com\Server\obj\Debug\Server.csproj.CopyComplete
......
此文件类型无法预览
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!