【问题标题】:How should one tear down a boost::asio::ip::udp::socket?应该如何拆除 boost::asio::ip::udp::socket?
【发布时间】:2009-08-03 14:23:13
【问题描述】:

我已经阅读了 boost asio 参考,阅读了教程并查看了一些示例。尽管如此,我还是看不出应该如何拆除套接字:

  1. 我应该调用 close() 还是由套接字的析构函数完成?
  2. 什么时候应该调用shutdown()
  3. shutdown() 的作用是什么? 我知道它“禁用发送或接收”,但这是如何完成的?如果在禁用套接字后使用套接字发送或接收,会发生什么情况?
  4. close() 会出现哪些错误

【问题讨论】:

    标签: boost-asio


    【解决方案1】:

    由于这是一个多问题,我会尽力回答每个部分,让您满意:

    1) 我对 ASIO 套接字的经验是由析构函数处理关闭套接字。但是,我只处理了 TCP 套接字。检查这一点的最好方法是简单地查看析构函数的代码,看看它是否做了任何类似于关闭的事情。我知道通过 Boost 代码可能有点棘手,因此简单地创建一个打开 UDP 套接字然后破坏它的小示例程序可能是最简单的。这样您就可以在调试器中单步执行代码以遵循逻辑。

    由于 Boost 的设计者在 TCP 套接字上考虑到了这一点,我很难想象他们不会对 UDP 套接字做同样的事情。

    2) 仅当您认为有必要阻止任何代码在套接字上执行未来的recv 和/或send 时才调用shutdown()。它通常不是必需的,尽管我已经看到它在 TCP 套接字上用于强制套接字在关闭时发送RST(与处理挂起发送的默认“优雅”关闭相反)。

    3) 您可以将套接字视为一种双通道通信形式:一个用于读取,另一个用于发送。您可以独立关闭其中一个通道,并且可以在另一个通道关闭时继续使用一个通道(即关闭发送后您仍然可以接收,反之亦然)。关闭套接字与在 recv 和 send 上调用 shutdown 相同。

    关闭 recv 只会阻止您的代码读取更多数据。如果您尝试这样做,您将收到一个套接字错误。同样,如果连接的另一端尝试向您发送数据,它将收到错误消息(很抱歉再次切换到 TCP 世界,但我相信 RST 会回复给发送者)。

    关闭发送同样会阻止您的代码发送更多数据。如果我没记错的话,这看起来与关闭套接字时发生的情况相同(发送一个零长度的数据包以向另一端发出特定通道已关闭的信号)。以后的任何发送尝试都将返回错误。

    4) 您必须检查您的文档才能确定。 MSDN 会给你一个很好的指示,虽然我不知道我是否认为它是权威的。

    【讨论】:

    • 谢谢,我已经弄清楚了一些,但我仍然不确定是否真的在套接字的析构函数中调用了 close()。我真正没有想到的是 boost asio 和传统网络编程之间的密切联系。您对 shutdown() 的解释和查看 msdn 套接字错误代码的建议都表明了这一点。 +1
    • FWIW,在 UDP 套接字上调用 .shutdown(BOTH) 在 Windows 上对我有效,但在 Linux 上却因为套接字未连接而崩溃。
    【解决方案2】:

    从 Boost 网站上给出的示例来看,您似乎应该简单地使用 close()。例如,看看这个:

    无效连接::stop() { socket_.close(); }

    取自这个地址:HTTP Server

    【讨论】:

      猜你喜欢
      • 2012-05-25
      • 2018-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      • 2017-04-27
      • 1970-01-01
      相关资源
      最近更新 更多