This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC3220S:如何正常重新启动 TCP 服务器

Guru**** 2540720 points
Other Parts Discussed in Thread: CC3220S

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/780076/cc3220s-how-to-gracefully-restart-tcp-server

器件型号:CC3220S

我将使用 CC3220S 与服务包#sp_3.5.0.0_2.0.0.0_2.2.0.5.bin 和 SDK v1.50.00.06来开发 TCP 服务器应用。 应用程序中有两个 TCP 服务器(两个不同的端口)。 程序工作正常、但我正在尝试改进代码、以便在客户端与端口断开连接时自动重新启动 TCP 服务器。 下面是我尝试和观察的内容:

1.其中一台 TCP 服务器从客户端接收固定数量的数据包,然后客户端应关闭端口连接。 我需要重新启动 TCP 服务器、以便它将来可以再次接受客户端连接。

  • 我使用 的是 SL_Recv、具有上的阻止选项(SL_SO_NONBLOCKING 设置为0)。
  • 当我完成收集所有数据包后、我对 sl_Recv 进行额外调用、直到它返回0。  
  • 然后我调用 sl_close
  • 在此之后、我的代码重新启动 TCP 服务器(sl_Socket、sl_Bind、sl_Listen)以等待客户端进行下一次连接。

我观察到、如果我没有在 sl_close 和随后的 sl_Bind 之间放置明显的延迟、sl_Bind 将返回 SL_ERROR_BSD_EADDRINUSE。  如果我在 sl_close 和 sl_Bind 之间放置了一个明显的延迟、那么它看起来是正确的。

问题:是否预计同一端口地址的 sl_close 和后续 sl_Bind 之间需要延迟? 在调用 sl_Bindd 之前、是否有更好的方法来检查地址状态?

2.我的另一台 TCP 服务器使用 sl_Send 将数据包无限期传输到客户端。 当然、客户端可以随时断开与端口的连接、我希望通过重新启动 TCP 服务器从这种情况中恢复。

  • 我正在使用 sl_Send、并且我已配置为阻止(sl_SO_NONBLOCKING 设置为0)。
  • 当客户端断开连接时、sl_Send 返回 SL_ERROR_BSD_SOC_ERROR。
  • 然后我尝试调用 sl_close、但 sl_close 调用永远不会返回。

问题:为什么 sl_close 不返回? 是否有更好的方法来处理这种情况?

谢谢、

Ruben

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Ruben:

    您的 SDK 版本略显过时。 特别是不建议使用 ServicePack 和更旧版本。 Service Pack 版本的是受 WPA KRACK 漏洞影响的设备。 此漏洞在版本3.6.0.3上修复。 您应该更新您的 SDK 版本和 ServicePack。

    返回到关闭插槽。 如果调用 sl_close(),则套接字不会立即关闭。 它是用于关闭 TCP 端口(四路握手)的"标准"过程。 但 TCP 端口的正确关闭取决于另一侧。 如果您需要立即关闭端口或将 sl_close()作为具有预定义超时的阻塞调用,则可以使用 so_linger 套接字选项。

    1月
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    1月、

    非常感谢您的帮助。 我不熟悉网络和 TCP、因此您的评论确实帮助我进行了更多挖掘。 我正在阅读有关 TCP 的 RFC793部分、以了解您的意思。

    我将在原始帖子中附加方案1的 Wireshark 跟踪图片。 CC3220为192.168.1.100、客户端为.101。 我期望的最后一个数据包是编号1629、那么我使用编号为1630的 SL_Recv? 检查客户端是否已断开连接。 我看到客户机的 FIN 编号为1631、我想这说明了 sl_Recv 返回0的原因。 然后、我使用 sl_close、我的 FIN 显示为1633。 最后、客户端 ACK 为1634。

    似乎一切都正常、但我的问题是 CC3220固件如何知道关闭的最后阶段何时发生? 是否可以使用回调或其他通知方法? 现在、我在 sl_close 调用后等待了100ms、然后重新启动服务器、但如果最终 ACK 需要更长时间、会怎么样? 我仍然需要在 SO_LINGER 上进行更多阅读、但我迄今为止所读的内容表明、这是一种关闭套接字的"蛮力破解"方式。

    -Ruben

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我还认为我看到了有关我的另一台服务器中发生的情况的线索(原始帖子中的场景#2)。 从下面的 Wireshark 跟踪中,我看到客户端(192.168.1.101) 在  发送 FIN 号为37之后发送了一个 RST 号为3940的 RST。 RST 在 CC3220 (192.168.1.100) 能够发送 FIN 之前到达、正如我 之前提到的、SL_Close 调用不会返回。  您在这方面建议 SO_LEGGER 是否有帮助? 问题-如果端口从客户端接收 RST、CC3220 NWP 是否会在 sl_close 调用中"挂起"? 文档中没有提到这样的内容。 再次感谢。

     

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    使用 CCS、我看到 CC3220在调用 sl_close 后实际上有一个异常。 现在、我需要弄清楚如何确定哪个异常及其原因。 很遗憾、SO_LEGGER 不会帮助您实现这一目标。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    -调用 sl_close()时没有发生硬故障的原因。 我同意您的代码或 SimpelLink 驱动程序中存在错误。 请确保您不会从异步处理程序上下文调用任何 SL_ API。 不允许出现这种行为。 我不知道 SimpleLink 驱动程序中与 sl_close()相关的错误。 但您可以在 changelog 中搜索较新版本的 SDK。 也许有人说 sl_close()有一些问题。 SO_LINGER 选项绝对不能帮助您解决硬故障。
    -当插座两侧均已正确关闭时,不会出现任何提示。 但为此、您可以使用 SO_LINGER 选项。 使用此选项可以阻止 sl_close()并在套接字正确关闭时返回(双面或在从 CC3220端通过 RST 超时)。

    1月
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Ruben:

    Jan 是正确的。 我怀疑主机驱动程序本身会导致它、您的代码中必须存在一些错误的用法。 您应该逐步完成代码并找出您最终进入 Hwi 的原因。 有一个被调用的函数会导致这种情况。 一旦您确定了该函数、就不应太难对其进行跟踪。

    编辑:看到您说 sl_close 会导致它、我的错误。 您能否提供该特定套接字实现的代码摘录?


    Jesu

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Jan 再次感谢大家的回答。 我将在关闭主题时将您的帖子标记为答案。

    耶稣也感谢你。 我已将相关代码离线发送给您。

    -Ruben

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我将项目更新为最新的 SDK (simplelink_cc32xx_sdk_2_40_02_00)和服务包(sp_3.10.0.5_2.0.0.0_2.2.0.6.bin)、并且行为相同。 当客户端突然退出时、sl_close 调用会挂起。 但是、我发现通过减小应用程序中的 TCP 数据包大小、我可以一起避免这个问题、以便关闭该线程。 再次感谢您的所有帮助!!