为什么Microsoft以不同的方式实现套接字?

And*_*eto 8 sockets networking winsock

我目前正处于涉及套接字的项目中,我只使用Linux的sys/socket.h文件.提示微软的端口,并意识到Winsock是不同的.我想我有两个问题.

首先,两种实现之间的主要区别是什么?是否有一种"翻译"它们的简单方法?我们非常感谢指南的链接,因为你们可能会给我提供比谷歌更优质的链接.

第二,为什么微软这样做?他们的动机是什么?为什么他们不像其他人一样保持相同的实施?

War*_*ung 19

Winsock的程序员的常见问题有如下的内容,BSD套接字兼容.(披露:我是FAQ的维护者.)

我没有真正涵盖那篇文章中的原因和原因,所以:

  • winsock.h vs sys/socket.h,arpa/inet.h,netinet/in.h等:这实际上我找到了一个改进.这是一套完整的功能,为什么不在单个标题中拥有它的所有定义?

  • close()vs. closesocket():回到Winsock发明的Windows 3天,Windows C++编译器都有某种POSIX API包装器来提供一些基本级别的可移植性,包括close().这些只是调用了编译器的stdio实现,因为DOS和Win16没有像Unices那样的统一I/O机制.你不能只在Win16中的描述符上调用close(),并使其工作独立于文件,套接字,管道等等.Win32与Winsock作为NT 3.5的一部分被发明的同时存在,并且它解决了这个问题,但是只有在NT衍生产品上使Winsock可用才会使MS在互联网上无关紧要,直到Windows XP.MS可能会很慢的游戏,但不是那个慢.最重要的是,使用POSIX机制的BSD套接字中的任何东西都与目标C++编译器提供的现有API冲突,而这些机制无法在Winsock中使用.他们必须为新功能提供相同的功能.

  • WSA*():这只是添加了功能,提供了BSD套接字没有的功能.很多都非常好,看到所有Unices中的类似机制会很好,但这不会很快发生.有一些竞争机制,比如aio*(),但并非所有Unices都可以使用,而不是Windows的可移植性.您可以忽略它并坚持使用基本套接字API,但在移植到Windows时这并不总是最佳选择.

  • errno与WSAGetLastError():errno是标准C的一部分,但错误值取决于C实现.请记住,Winsock一开始并不是微软特有的.DOS和Windows并没有开始使用标准网络API.这是由第三方提供的,他们聚在一起并发明了Winsock,与微软有关.最初的Winsock堆栈都是第三方.由于几个原因,他们无法编写规范来覆盖C RTL的errno值.这些错误值属于供应商提供的winsock.dll,与C RTL完全不同.

  • WSAStartup(),WSACleanup():这也是因为winsock.dll最初是第三方提供的东西,它与一些不属于操作系统的底层网络堆栈接口.此外,还有Win16方面的事情:Win16无法看到程序刚刚死亡并自动清理其分配的资源.您必须在程序退出之前明确释放所有内容,否则它们将被泄露.

  • 缺乏readv()等:这在Winsock诞生的第三方/ Win16世界中没有意义.


Ric*_*dle 14

如果我错过了这一点,请原谅我,但是你是否正在关注WSARecv和系列,并认为Windows上的整个套接字API与Berkeley套接字API不同?

Berkeley API确实存在于Windows上(参见recv和family),并且与其他任何Berkeley套接字实现基本兼容.

有关将套接字代码移植到Windows的信息,请参阅MSDN文章"将套接字应用程序移植到Winsock".

  • @Andrew:“想知道语法为何不同”:我的意思是语法*没有*不同-您在Linux上使用的Berkeley Sockets API也可以在Windows上使用。还是我们出于不同目的而说话?您是否有语法差异示例? (2认同)