11

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

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

2 回答 2

10

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

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

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

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

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

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

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

4) You'll have to check your docs to know for certain. MSDN will give you a pretty good indication, though I don't know that I'd consider it to be authoritative.

于 2009-11-09T17:46:24.040 回答
1

From the examples given at Boost website, it seems as if you should simply use close(). For instance, look at this one:

void connection::stop()
{
  socket_.close();
}

Taken from this address: HTTP Server

于 2011-05-12T18:57:06.353 回答