Commit 59b2af93 张东亮

11

1 个父辈 53cce1c4
正在显示 103 个修改的文件 包含 1264 行增加183 行删除
此文件类型无法预览
......@@ -31,16 +31,18 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net">
<HintPath>.\log4net.dll</HintPath>
<Reference Include="log4net, Version=2.0.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.12\lib\net45\log4net.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>.\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
......@@ -55,5 +57,8 @@
<Compile Include="Node.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
......@@ -10,6 +11,51 @@ namespace Agv
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>
......@@ -19,9 +65,11 @@ namespace Agv
{
try
{
string json =JsonHelper.SerializeObject(node);
string json = JsonHelper.SerializeObject(node);
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;
}
catch (Exception ex)
......@@ -42,7 +90,12 @@ namespace Agv
{
string json = JsonHelper.SerializeObject(nodes);
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;
}
catch (Exception ex)
......@@ -94,6 +147,23 @@ namespace Agv
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>
......
......@@ -27,5 +27,9 @@ namespace Agv
{
LOGGER.Error(errorMsg, ex);
}
public static void warn(string warn)
{
LOGGER.Warn(warn);
}
}
}
......@@ -36,7 +36,10 @@ namespace Agv
/// 料架类型
/// </summary>
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,
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
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\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.CopyComplete
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.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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
......@@ -22,7 +23,6 @@ namespace Agv
private Thread tRecon;
private string SERVER_IP; //远程IP地址
private int SERVER_PORT; //端口
private bool _IsEecodeSingleNode = false;//是否编码单个节点(默认编码多个节点)
/// <summary>
/// 小车接收事件委托
/// </summary>
......@@ -54,12 +54,10 @@ namespace Agv
/// <summary>
/// AGV客户端
/// </summary>
/// <param name="_IsEecodeSingleNode">编码方式,默认编码多个节点</param>
public AgvClient(bool _IsEecodeSingleNode = false)
public AgvClient()
{
_node = new List<Node>();
_nodeNoneState = new List<Node>();
this._IsEecodeSingleNode = _IsEecodeSingleNode;
}
/// <summary>
......@@ -96,7 +94,6 @@ namespace Agv
//Open();
tListen.Start();
tSend.Start();
Agv.log.info("连接服务器");
}
/// <summary>
......@@ -107,12 +104,12 @@ namespace Agv
CancelState = true;
_loopClient = false;
_loopRecon = false;
SendStatus();
if (_clientSocket != null)
{
_clientSocket.Close();
_clientSocket = null;
}
log.info("客户端关闭");
}
/// <summary>
......@@ -142,7 +139,7 @@ namespace Agv
};
_node.Add(node);
_nodeNoneState.Add(new Node { Name=nodeName});
log.info("SetStatus " + node.ToText());
log.info(string.Format("SetStatus To Server[{0}]:[{1}]", ServerInfo, node.ToText()));
}
else
{
......@@ -152,26 +149,7 @@ namespace Agv
_node[index].Shelf = shelf;
_node[index].Type = type;
_node[index].Mark = mark;
log.info("SetStatus " + _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());
log.info(string.Format("SetStatus To Server[{0}]:[{1}]", ServerInfo, _node[index].ToText()));
}
}
......@@ -190,17 +168,16 @@ namespace Agv
if (IsConn)
{
_countRecon = 0;
log.info("连接服务器成功");
log.info(string.Format("连接到服务端[{0}]成功",ServerInfo));
Connected?.Invoke(IsConn);
}
else
{
log.info("连接服务器失败" + ++_countRecon + "次");
log.warn("连接服务器失败" + ++_countRecon + "次");
}
}
Thread.Sleep(2000);
}
log.info("Quit Thread Reconnect");
}
/// <summary>
......@@ -250,7 +227,7 @@ namespace Agv
byte[] arrMsgRec = new byte[1024];
// 将接收到的数据存入到输入 arrMsgRec中;
int length = -1;
if (_clientSocket.Poll(-1, SelectMode.SelectRead))
if (_clientSocket!=null && _clientSocket.Poll(-1, SelectMode.SelectRead))
{
try
{
......@@ -263,19 +240,11 @@ namespace Agv
break;
}
}
catch (SocketException se)
{
IsConn = false;
Connected?.Invoke(IsConn);
log.error(string.Format("客户端[{0}]接收服务端[{1}]的消息出现异常", _clientSocket.RemoteEndPoint.ToString(), ServerInfo), se);
break;
}
catch (Exception e)
catch (ObjectDisposedException ode)
{
IsConn = false;
Connected?.Invoke(IsConn);
log.error(string.Format("客户端[{0}]接收服务端[{1}]的消息出现异常", _clientSocket.RemoteEndPoint.ToString(), ServerInfo), e);
break;
log.info(string.Format("客户端已关闭"));
}
}
......@@ -283,36 +252,14 @@ namespace Agv
{
byte[] buff = new byte[length];
Array.Copy(arrMsgRec, 0, buff, 0, length);
Node node = Common.Decode(buff);
if (node == null)
{
log.error("命令解析失败");
}
else
{
log.info("触发Received事件," + node.ToText());
Received?.Invoke(node);
}
StickyBagHandle(buff);
}
//if (_clientSocket.Available > 0)
//{
// int count = _clientSocket.Receive(temp);
// byte[] buff = new byte[count];
// Array.Copy(temp, 0, buff, 0, count);
// Node node = Common.Decode(buff);
// if (node == null)
// {
// LogUtil.error("命令解析失败");
// }
// else
// {
// LogUtil.info("触发Received事件," + node.ToText());
// Received?.Invoke(node);
// }
//}
}
catch (SocketException se)
{
IsConn = false;
Connected?.Invoke(IsConn);
log.error(string.Format("客户端接收服务端[{0}]的消息出现异常", ServerInfo), se);
}
catch (Exception ex)
{
......@@ -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>
private void KeepSendStatus()
{
bool bln;
while (_loopClient)
{
Thread.Sleep(SendSleep * 1000);
if (!IsConn) continue;
if (_clientSocket == null) continue;
if (_IsEecodeSingleNode)
{
for (int i = 0; i < _node.Count; i++)
{
if (!_loopClient) break;
Thread.Sleep(500);
if (!CancelState)
{
byte[] buff = Common.Encode(_node[i]);
bln = Send(buff);
}
else
{
Node nostate = _node[i].ToCopy();
nostate.Action = ClientAction.None;
byte[] buff = Common.Encode(nostate);
bln = Send(buff);
}
if (!bln) continue;
}
}
else
SendStatus();
}
}
private void SendStatus()
{
bool bln;
if (Common.EnDecodeSingleNode)
{
for (int i = 0; i < _node.Count; i++)
{
if (_node.Count == 0) continue;
Thread.Sleep(100);
if (!CancelState)
{
byte[] buff = Common.Encode(_node);
if (!_loopClient) break;
byte[] buff = Common.Encode(_node[i]);
bln = Send(buff);
}
else
{
byte[] buff = Common.Encode(_nodeNoneState);
if (!_loopClient) break;
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) 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>
......@@ -396,10 +446,9 @@ namespace Agv
try
{
if (!_loopRecon) return false;
if (buff == null) return false;
_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;
}
catch (Exception ex)
......@@ -436,7 +485,7 @@ namespace Agv
ping.Dispose();
if (result.Status != System.Net.NetworkInformation.IPStatus.Success)
{
log.info("Ping " + ip + " 请求没有响应");
log.warn("Ping " + ip + " 请求没有响应");
return false;
}
return true;
......
......@@ -35,9 +35,6 @@
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\..\..\..\DLL\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web.Extensions" />
......
此文件的差异太大,无法显示。
b85b5ff4afa439da48046bd004c84f66501d0684
7d5e8676cee1b0e36ad2454791cf299bb510c5f0
......@@ -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.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\log4net.xml
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.CopyComplete
......
......@@ -34,11 +34,13 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\..\..\DLL\log4net.dll</HintPath>
<Reference Include="log4net, Version=2.0.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.12\lib\net45\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
......@@ -71,6 +73,7 @@
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
......
......@@ -7,19 +7,19 @@
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
<log4net>
<appender name="AgvClient" type="log4net.Appender.RollingFileAppender">
<file value="logs/AgvClient.log"/>
<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]%-5p %m%n"/>
<conversionPattern value="[%date][%t][%c:%L]%-5p %m%n"/>
</layout>
</appender>
<root>
<level value="debug"/>
<appender-ref ref="AgvClient"/>
<level value="Info"/>
<appender-ref ref="Agv"/>
</root>
</log4net>
</configuration>
......@@ -43,7 +43,6 @@
this.comboBox2 = new System.Windows.Forms.ComboBox();
this.comboBox3 = 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.label9 = new System.Windows.Forms.Label();
this.label10 = new System.Windows.Forms.Label();
......@@ -53,10 +52,17 @@
this.button4 = new System.Windows.Forms.Button();
this.button5 = new System.Windows.Forms.Button();
this.label11 = new System.Windows.Forms.Label();
this.label12 = new System.Windows.Forms.Label();
this.button6 = new System.Windows.Forms.Button();
this.label13 = new System.Windows.Forms.Label();
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();
//
// button1
......@@ -190,15 +196,6 @@
this.comboBox4.Size = new System.Drawing.Size(121, 20);
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
//
this.textBox4.Location = new System.Drawing.Point(365, 12);
......@@ -231,13 +228,13 @@
this.textBox5.Name = "textBox5";
this.textBox5.Size = new System.Drawing.Size(100, 21);
this.textBox5.TabIndex = 19;
this.textBox5.Text = "12000";
this.textBox5.Text = "9501";
//
// button2
//
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.Location = new System.Drawing.Point(314, 77);
this.button2.Location = new System.Drawing.Point(12, 235);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(138, 38);
this.button2.TabIndex = 20;
......@@ -249,7 +246,7 @@
//
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.Location = new System.Drawing.Point(314, 180);
this.button3.Location = new System.Drawing.Point(348, 235);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(138, 38);
this.button3.TabIndex = 21;
......@@ -284,26 +281,17 @@
// label11
//
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.Size = new System.Drawing.Size(65, 12);
this.label11.TabIndex = 24;
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
//
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.Location = new System.Drawing.Point(314, 128);
this.button6.Location = new System.Drawing.Point(177, 235);
this.button6.Name = "button6";
this.button6.Size = new System.Drawing.Size(138, 38);
this.button6.TabIndex = 26;
......@@ -314,7 +302,7 @@
// label13
//
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.Size = new System.Drawing.Size(89, 12);
this.label13.TabIndex = 27;
......@@ -333,15 +321,78 @@
this.button7.UseVisualStyleBackColor = false;
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
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
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.label13);
this.Controls.Add(this.button6);
this.Controls.Add(this.label12);
this.Controls.Add(this.label11);
this.Controls.Add(this.button5);
this.Controls.Add(this.button4);
......@@ -351,7 +402,6 @@
this.Controls.Add(this.label10);
this.Controls.Add(this.label9);
this.Controls.Add(this.textBox4);
this.Controls.Add(this.label8);
this.Controls.Add(this.comboBox4);
this.Controls.Add(this.comboBox3);
this.Controls.Add(this.comboBox2);
......@@ -373,7 +423,10 @@
this.ShowIcon = false;
this.Text = "agv对接模拟客户端";
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.groupBox1.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
......@@ -396,7 +449,6 @@
private System.Windows.Forms.ComboBox comboBox2;
private System.Windows.Forms.ComboBox comboBox3;
private System.Windows.Forms.ComboBox comboBox4;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.TextBox textBox4;
private System.Windows.Forms.Label label9;
private System.Windows.Forms.Label label10;
......@@ -406,10 +458,15 @@
private System.Windows.Forms.Button button4;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.Label label11;
private System.Windows.Forms.Label label12;
private System.Windows.Forms.Button button6;
private System.Windows.Forms.Label label13;
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
private void Form1_Load(object sender, EventArgs e)
{
Agv.Common.EnDecodeSingleNode = false;
server = new Agv.Server();
server.NodeChanged += Server_NodeChanged;
server.NodeOnline += Server_NodeOnline;
......@@ -37,39 +38,32 @@ namespace AgvClientTest
client.Connected += Client_Connected;
}
private void Client_Log(string s)
{
Agv.log.info(s);
}
private void Server_NodeChanged(Agv.Node clientNode)
{
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)
{
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)
{
//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 i2 = comboBox2.SelectedIndex;
int i3 = comboBox4.SelectedIndex;
......@@ -80,7 +74,11 @@ namespace AgvClientTest
//client.SetStatus(textBox1.Text,textBox3.Text,textBox2.Text, (Agv.ClientAction)i1,
// (Agv.ClientLevel)i2,(Agv.ClientShelf)i3,
// (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();
......@@ -123,7 +121,6 @@ namespace AgvClientTest
private void button4_Click(object sender, EventArgs e)
{
client.Connect(textBox4.Text, int.Parse(textBox5.Text));
}
......@@ -131,6 +128,8 @@ namespace AgvClientTest
{
this.Invoke(new Action(() =>
{
if (label3 == null)
return;
if (!status)
label13.BackColor = Color.Red;
else
......@@ -143,7 +142,8 @@ namespace AgvClientTest
{
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
}
}
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>
此文件的差异太大,无法显示。
......@@ -7,19 +7,19 @@
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
<log4net>
<appender name="AgvClient" type="log4net.Appender.RollingFileAppender">
<file value="logs/AgvClient.log"/>
<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]%-5p %m%n"/>
<conversionPattern value="[%date][%t][%c:%L]%-5p %m%n"/>
</layout>
</appender>
<root>
<level value="debug"/>
<appender-ref ref="AgvClient"/>
<level value="Info"/>
<appender-ref ref="Agv"/>
</root>
</log4net>
</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
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.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\Agv.Client.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\log4net.xml
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.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
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
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\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.csproj.CoreCompileInputs.cache
E:\Neotel\Projects\Gitee\AGV-Com\Server\obj\Debug\Server.csproj.CopyComplete
......
此文件类型无法预览
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!