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

ckv*_*ckv 2 c++ winapi winsock

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

如果手柄m_Socket1500,那么将它的值是什么时,shutdownclosesocket函数调用就可以了?

shutdown(m_SocServer, 2);
closesocket(m_SocServer);
Run Code Online (Sandbox Code Playgroud)

val*_*ldo 7

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

  1. 在套接字上执行操作,其中一些可能使其处于不可用状态.
  2. 终止插座手柄.

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

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

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

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

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

对于某些人来说,INVALID_SOCKET在调用closesocket它之后立即为套接字变量赋值是一个很好的做法.

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


R S*_*hko 5

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

一旦你打电话closesocket,那个套接字标识符是免费的,可以通过另一个调用再次返回socket.如果closesocket再次呼叫,则不是关闭原始套接字,而是关闭新重新插入的套接字