c# - 超时后重新连接到 TCP 客户端
问题描述
我刚刚完成了通过 C# 中的应用程序控制的自动滑动门的编程。该应用程序通过 TCP/IP 以太网与移动门的电机进行通信。我现在必须制作另一个可以同时控制两扇门的版本。我立即遇到了一个问题,如果我尝试同时发送命令,我尝试与之通信的第二个电机将立即断开连接。我主要通过设置两个后台工作者来解决这个问题。每个工人在每个循环中从每个电机加载所有必要的变量,并发送当前排队的任何命令。不幸的是,电机偶尔会出现命令溢出和连接松动的情况。发生这种情况时,我无法重新连接。这是我发送电机命令的功能:
public string[] SendMotorCommand(string motorCommand, bool timeout = true, int timeoutMS = 2000)
{
string[] messagesReceived = null;
if (connected)
{
try
{
//example from: http://stackoverflow.com/questions/10182751/server-client-send-receive-simple-text
//---create a TCPClient object at the IP and port no.---
NetworkStream nwStream = Client.GetStream();
if (timeout)
nwStream.ReadTimeout = timeoutMS;
else
nwStream.ReadTimeout = -1;
byte[] bytesToSend = Encoding.ASCII.GetBytes(motorCommand + "\r");
nwStream.Write(bytesToSend, 0, bytesToSend.Length);
/*if (motorCommand.Contains("PR"))
{*/
//---read back the text---
byte[] data = new byte[Client.ReceiveBufferSize];
int bytesRead = nwStream.Read(data, 0, data.Length);
string str = Encoding.ASCII.GetString(data, 0, bytesRead).Trim();
messagesReceived = str.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
//}
}
catch (Exception ex)
{
Debug.WriteLine("Failed to send or receive command " + motorCommand + " at IP " + ip);
Debug.WriteLine(ex);
Client.Close();
Client = new TcpClient();
Client.Connect(ip, 503);
}
}
return (messagesReceived);
}
如您所见,如果电机无法通信,我会关闭当前客户端并重新创建它,但是,在初始通信失败后我永远无法重新连接。我能让它们再次工作的唯一方法是重新启动应用程序。以太网连接没有任何改变的事实让我认为,如果连接失败,我应该能够可靠地重新建立连接。
这些命令中可能有大约 20 个循环运行,但有许多命令可能会排队,尤其是在命令不断超时的情况下。是否有可能一堆命令正在排队,而这些命令仍在由以太网接口处理?作为临时修复,我将我的应用程序设置为在命令失败时自行重启,当发生这种情况时,它通常会重启几次,然后再继续运行。这让我觉得还有一些事情正在处理中。
解决方案
看起来这是我的命令队列的问题。
这就是我的命令被发送的方式:
string[] currentCommands = commands.ToArray();
commands.Clear();
foreach (string command in currentCommands)
{
SendMotorCommand(command);
}
看起来是随机的,这个字符是作为命令发送的 () 不知道如何显示它,但它看起来像一个更高的小 L。这似乎使通讯中断。不确定它是如何进入那里的,因为我从未将此字符添加到队列中,但我怀疑它与将命令转换为数组有关。如果在循环运行时添加命令,这可能会被中断。我现在正在检查“SendMotorCommand”功能以跳过该命令(如果这是正在发送的内容)。这解决了问题,但如果有人有想法,想知道为什么会发生这种情况。
推荐阅读
- angular - 在 Angular (7x) 中创建多模块项目应用程序的方法?对于铬分机
- javascript - 有没有办法只允许读写规则来自指定的url?
- regex - 如何使用过滤器仅在 Google 表格中显示包含日语的单元格?
- javascript - 当 css 样式为 height: 100% 时检测滚动及其方向;和溢出:滚动;
- excel - 无缝链接来自越来越多 Excel 电子表格的时间序列数据
- python - 如何遍历另一个 .py 文件上的列表?
- sql - 将列的每个值除以表中的记录总数
- python-3.x - Python3如何将日期转换为第一个周期是九月的月度周期
- java - 如何在二维数组中创建不同的列大小
- r - 此警告的含义;“警告消息:在 get(object, envir = currentEnv, inherits = TRUE) 中:重新启动中断的承诺评估”