我目前正处于涉及套接字的项目中,我只使用Linux的sys / socket.h文件。提示微软的端口,并意识到Winsock是不同的。我想我有两个问题。
首先,两种实现之间的主要区别是什么?是否有一种“翻译”它们的简单方法?我们非常感谢指南的链接,因为你们可能会得到比谷歌更好的链接。
其次,为什么微软这样做?他们的动机是什么?为什么他们不像其他人一样保持相同的实施?
答案 0 :(得分:17)
Winsock Programmer's FAQ有一节关于此BSD Sockets Compatibility。 (披露:我是FAQ的维护者。)
我并没有真正涵盖那篇文章的原因和内容,所以:
winsock.h vs sys / socket.h,arpa / inet.h,netinet / in.h等:这实际上我找到了改进。这是一套完整的功能,为什么不在一个标题中包含它的所有定义呢?
close()与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世界中没有意义。
答案 1 :(得分:13)
如果我错过了这一点,请原谅我,但是您是否正在关注WSARecv和家人,并认为Windows上的整个套接字API与Berkeley套接字API不同?
Berkeley API确实存在于Windows上(请参阅recv和系列),并且与其他任何Berkeley套接字实现基本兼容。
有关将套接字代码移植到Windows的信息,请参阅MSDN文章"Porting Socket Applications to Winsock"。
答案 2 :(得分:0)
尝试使用ACE - 它是一个很棒的跨平台通信库。
答案 3 :(得分:0)
Milen在评论中说道,但Apache Portable Runtime库涵盖了网络应用程序的许多可移植性问题。