在同一个套接字上调用shutdown和closesocket两次

时间:2010-06-25 04:34:45

标签: c++ winapi winsock

在我的应用程序中,我在同一个套接字上调用shutdownclosesocket两次函数。我知道这是不对的,我必须确保只调用一次这些函数。但是为什么这些调用中的任何一个在第二次调用时都不会失败?

如果m_Socket的句柄为1500,那么在调用shutdownclosesocket函数时它的价值是什么?

shutdown(m_SocServer, 2);
closesocket(m_SocServer);

3 个答案:

答案 0 :(得分:7)

第一个必须区分两个不同的东西:

  1. 在套接字上执行操作,其中一些可能会使其处于无法使用状态。
  2. 终止套接字句柄。
  3. 使用参数2(shutdown)调用SD_BOTH是(1)。也就是说,刷新所有挂起的缓冲区,并丢弃所有的接收缓冲区。这样你就不能再读/写了。但是,您仍然拥有有效的套接字句柄。如果需要,您仍然可以查询/设置其选项。例如,可以在其上调用getpeername来发现您所连接的地址。 此外,根据实现,再次调用shutdown不一定会导致错误。也许它有累积效应。

    另一方面,调用closesocket是(2)。一旦你调用它 - 你不能对该套接字句柄做任何事情。它现在无效。

    如果socket的值为1500,即使在调用closesocket之后,它仍然会有它。因为它只是一个变量。这就像在delete之后询问指针会有什么值。

    但是这个套接字值(1500)不再有效。您无法使用此值调用任何套接字函数。

    此外,如果同时创建另一个套接字 - 它很可能会收到相同的数字。在这里,您可能会发现自己处于一个更严重的问题 - 在另一个套接字上执行操作而不会注意到它。

    对于某些人来说,最好在调用INVALID_SOCKET之后立即为套接字变量分配closesocket值。

    P.S。 也许调用shutdown + closesocket并不会特别失败,因为你正在关闭另一个套接字。

答案 1 :(得分:5)

第一次调用closesocket后是否收到错误取决于代码的其余部分是做什么的。

拨打closesocket后,该套接字标识符是免费的,可以通过另一次调用socket再次返回。如果再次拨打closesocket,则不会关闭原始套接字,而是关闭新重新插入的

答案 2 :(得分:1)

他们确实失败了。尝试关注代码段。

SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
closesocket(s);   // OK

shutdown(s, 2);   // fails
closesocket(s);   // fails