close()和closesocket()可以互换使用吗?

13

我在这里看到很多答案都建议使用 close() 来销毁socket,但我所使用的来自msdn 的指南让我使用 closesocket()。我想知道两者之间是否有区别,以及使用其中一个或另一个的原因。

在这两种情况下,我都看到建议使用 shutdown(),所以都可以正常使用。


你确定你没有混淆 Linux 的 close() 和 Windows 的 closesocket() 吗? - Mohamad Elghawi
6
我认为 close() 是*nix系统下的函数;而closesocket() 则是Windows平台下的等效函数。 - Jonathan Potter
1个回答

22

close()是*nix函数。它适用于任何文件描述符,而Unix中的套接字就是文件描述符的一种实例,因此它也可以正确地关闭套接字。

closesocket()是Windows特定的函数,专门用于处理套接字。Windows上的套接字不使用*nix-style文件描述符,socket()返回一个内核对象句柄,所以必须使用来关闭它。

我觉得挺遗憾的,BSD-sockets没有包含与socket函数对应的特定函数,这样就可以在任何地方使用 - 但生活就是这样。

最后,不要将shutdown套接字与关闭套接字混淆。 shutdown()会停止套接字上的传输,但套接字仍然存在于系统中,与它相关联的所有资源也保持不变。在关闭套接字之前,您仍然需要将其关闭。


2
BSD比Linux早十年问世。他们没有预测到未来,但这并不可耻。 - user207421
2
@EJP,我认为,良好的设计意味着如果你有一个创建某些东西的函数,你需要有一个删除你所创建内容的函数,并且不依赖于特定于操作系统的实现细节。 - SergeyA
2
@SergeyA,我不知道你在说什么。BSD 一个操作系统,并且它重用了现有的close()函数,该函数已经关闭文件FD,也可以关闭套接字FD,在BSD中,套接字FD是相同类型的对象。十年后,Winsock出现了,因为Windows套接字句柄与Windows文件句柄不是同一种类型的东西,所以必须添加closesocket()。那么,为什么这是BSD的错,而且可耻呢? - user207421
1
如果BSD添加了closesocket()来关闭套接字文件描述符,为了一致性,他们还想添加closedevice()来关闭设备文件描述符,closepipe()来关闭管道文件描述符,closeshmem()来关闭共享内存文件描述符,closeserialport()来关闭串口文件描述符,等等……或者他们可以只保留适用于所有文件描述符的单个函数close(),并将不灵活、令人困惑的API留给Windows用户。 - Jeremy Friesner
2
我的经验恰恰相反。我曾经花了几周时间追踪一个讨厌的资源泄漏问题;结果发现,这个泄漏是因为通过调用popen()创建的(FILE *)句柄被调用fclose()关闭(因为fclose()被记录为在使用完后关闭(FILE *)的方法)--但是fclose()调用并没有起作用,因为实际上有一个单独的pclose()调用你必须使用,而这对代码作者来说并不明显。寓意:只有在编译时捕获到任何配对错误时,成对的打开/关闭调用才有所帮助。 - Jeremy Friesner
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接