为什么有socket(),connect(),send()等的WSA挂件,而不是closesocket()?

Oli*_*aur 11 c++ sockets winapi winsock

我将尝试用一些例子来解释我的意思:

  • socket() - > WSASocket()
  • connect() - > WSAConnect()
  • send() - > WSASend()
  • sendto() - > WSASendTo()
  • recv() - > WSARecv()
  • recvfrom() - > WSARecvFrom()
  • ...
  • closesocket() - > WSA ???()

这没什么大不了的,但仍然让我头痛欲绝.

War*_*ung 41

要理解这一点,你必须意识到Winsock是在20世纪90年代早期创建的,当时Windows 3.x恐龙在地球上漫游.

Windows套接字("Winsock")API镜像了大多数BSD套接字API:两者都提供给定的功能,两者都做同样的事情.因此,socket()在两个API下都是相同的调用.在某些地方存在细微差别,但没有什么比基于BSD套接字的其他系统(如Linux和OS X)的网络编程差异更大.

除了实现该公共基础API之外,Winsock API还为BSD套接字提供了许多扩展.许多名称的名称与原始函数类似,但WSA其他所有内容都带有前缀和驼峰大小写.这些是原始功能的纯扩展版本,而不是它们的替代品.您可以选择使用哪一个,具体取决于您是否需要扩展功能以及您的程序是否必须可移植到仅提供BSD套接字API的系统.例如,WSASocket()采用socket()与其他三个额外的参数相同的参数,这些参数与其他Winsock扩展有关.如果你不需要扩展,那么调用就没有真正的惩罚,socket()除此之外你还获得了便携性的好处.

除了这些简单的扩展之外,还有没有直接BSD等效的Winsock扩展,例如WSAAsyncSelect().与Unixy系统的程序相比,这些通常与Windows程序编写方式的差异有关.在这种特殊情况下,WSAAsyncSelect()存在使编写单线程GUI程序更容易,这些程序使用套接字而没有网络I/O阻塞GUI,反之亦然.这在今天很有用,但对于Winsock在Windows 3.1时代的成功绝对至关重要,因为它没有线程或其他有用的多处理和IPC机制.

这使得只有少数oddballs喜欢closesocket()ioctlsocket().

closesocket()close(2)POSIX/Unix下的相同,只是它只接受套接字,而不是文件句柄.这是名称变更的部分原因,但真正的原因来自于我在上面提到的20世纪90年代早期的历史问题.在那些日子里,一些Windows编译器-有更多的 可用 比今天-包括POSIX API等价物,以便于从其他平台到Windows移植的代码.这些功能非常有限,并且不包括套接字支持,但是,close()当时在Windows上认为功能名称被"采用".事实并非如此,但Winsock是其历史的产物,现在无法改变.

ioctlsocket()vs 的故事ioctl()是相似的.一个很大的区别是,ioctlsocket()ioctl()Unix系统相比,它在Windows上受到很大限制.它的存在只是为了向Windows提供一些与网络相关的功能,原始的Winsock创建者认为这些功能在BSD套接字API中很有用.多年来,您使用套接字和ioctl()Unixy系统但未使用的许多功能ioctlsocket()已经通过其他API添加到Windows中,其中一个就是WSAIoctl().

我已经为Winsock程序员的常见问题解答(我维护的)撰写了一篇关于" Winsock的历史 "的文章,其中详细介绍了所有这些.另一篇相关文章是" BSD套接字兼容性".

  • 令我惊讶的是,这个富有洞察力的答案并没有得到更多的关注.来自我的+1. (4认同)

Bri*_*ndy 3

closesocket仅在 Windows 上可用,但我不确定为什么他们不遵循 WSA 约定。如果它真的让你烦恼,你可以制作自己的包装器来调用 closesocket。

正如WSASocket中提到的,应该调用 closesocket。