在我的应用程序中,我在同一个套接字上调用shutdown
和closesocket
两次函数。我知道这是不对的,我必须确保只调用一次这些函数。但是为什么这些调用中的任何一个在第二次调用时都不会失败?
如果m_Socket
的句柄为1500
,那么在调用shutdown
和closesocket
函数时它的价值是什么?
shutdown(m_SocServer, 2);
closesocket(m_SocServer);
答案 0 :(得分:7)
第一个必须区分两个不同的东西:
使用参数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