gpt4 book ai didi

c# - C#同步TCP客户端套接字无法解释的丢失数据

转载 作者:行者123 更新时间:2023-12-03 12:01:30 25 4
gpt4 key购买 nike

我在不可靠的移动数据连接上使用TCP,这可能会由于干扰或信号强度出现问题而丢弃数据包。

使事情变得复杂的是,我正在使用Modbus TCP,另一端的移动路由器将其转换为Modbus RTU(串行),以便与基于串行的设备(从站)进行通信。

此外,每当将读取请求发送到串行设备时,一旦发送响应,其内部指针就会增加到下一个数据块。串行设备不知道移动连接是否还可以;如果响应没有完全返回到服务器,则无论如何它已经增加了其内部指针。

换句话说,采取以下情况:

  • 服务器通过TCP发送modbus读取请求。
  • 路由器接收请求并将其传递给串行设备。
  • 串行设备响应路由器。
  • 串行设备递增数据指针。
  • 路由器无法将TCP数据包发送回服务器。
  • 服务器再次发送读取请求。
  • 串行设备响应路由器。
  • 串行设备递增数据指针。
  • 路由器成功将数据发送回服务器。

  • 在上述情况下,您将看到步骤5中的问题导致丢失了整个数据块,因为串行设备不知道先前的读取操作实际上失败了。它已经移到下一个块了!通常,我要做的就是检测到此问题,并使用“请求先前的数据块”操作来重新请求串行设备中先前丢失的数据块。

    这是我的问题:即使我将所有内容包含在SystemException try-catch块中,并且正在检查返回值,我也无法从TCP代码中获取任何异常或错误。

    我仔细查看了日志文件,发现请求和响应之间的时间大约为1秒,但是在怀疑丢失数据块时,时间间隔为2到3秒。这表明发生了发送,但是没有接收到数据,因此再次尝试发送。但是,当然,当再次尝试时,串行设备应该已经将其数据指针增加到下一组数据。

    由于某种原因,串行设备收到了读取请求,但是数据从未将其返回给服务器。

    我不是TCP/IP专家,所以外面有人知道会发生什么吗? TCP是否可以在不引起异常且我不知情的情况下“在后台”重新发送数据包?

    在我的代码中,我只是在做这样的事情:
    _log.Debug(string.Format("[{0}]: Sending sync response ({1}).", 
    this._IP.ToString(), CoreUtils.PayloadToString(write_data)));

    tcpSynCl.Send(write_data, 0, write_data.Length, SocketFlags.None);
    int result = tcpSynCl.Receive(tcpSynClBuffer, 0,
    tcpSynClBuffer.Length, SocketFlags.None);

    byte function = tcpSynClBuffer[7];
    byte[] data;

    if (result == 0) throw SystemException("No data received");

    // ... process log buffer ...

    _log.Debug(string.Format("[{0}]: Got sync response ({1}).",
    this._IP.ToString(), CoreUtils.PayloadToString(data)));

    return data;

    没有抛出任何异常,这表明在后台的Send()和Receive()之间发生了某些事情。两个调试日志条目之间的时间是所有其他调试日志条目的两倍。可能还是不可能?

    最佳答案

    首先:接收0字节并不意味着您什么都没收到。这意味着连接已关闭。

    第二:由于Nagle算法,您可能会同时收到两条消息。您需要检查接收到的字节,然后查看其中的消息。 TCP不是基于消息,而是基于流。

    关于c# - C#同步TCP客户端套接字无法解释的丢失数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7577673/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com