我目前正在进行一个涉及套接字的项目,我只使用 Linux 的 sys/socket.h 文件。将端口提示给 Microsoft,并意识到 Winsock 是不同的。我想我有两个问题。
首先,这两种实现之间的主要区别是什么?有没有一种简单的方法来“翻译”它们?一个指向指南的链接将不胜感激,因为你们可以获得比谷歌更好的链接。
其次,微软为什么要这么做?他们的动机是什么?为什么他们不保持与其他人相同的实施方式?
我目前正在进行一个涉及套接字的项目,我只使用 Linux 的 sys/socket.h 文件。将端口提示给 Microsoft,并意识到 Winsock 是不同的。我想我有两个问题。
首先,这两种实现之间的主要区别是什么?有没有一种简单的方法来“翻译”它们?一个指向指南的链接将不胜感激,因为你们可以获得比谷歌更好的链接。
其次,微软为什么要这么做?他们的动机是什么?为什么他们不保持与其他人相同的实施方式?
Winsock Programmer's FAQ有一个关于此的部分,BSD Sockets Compatibility。(披露:我是常见问题解答的维护者。)
我并没有真正涵盖在那篇文章中的原因和原因,所以:
winsock.h 与 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 与作为 NT 3.5 的一部分发明 Winsock 的同时存在,它解决了这个问题,但如果 Winsock 仅在 NT 衍生产品上可用,那么在 Windows XP 之前,MS 在 Internet 上已经不相关了。MS对游戏可能很慢,但不是那样慢的。最重要的是,BSD 套接字中使用 POSIX 机制的任何内容与针对它的 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 世界中没有意义。
如果我错过了重点,请原谅我,但是您是否正在查看WSARecv及其家族,并认为 Windows 上的整个套接字 API 与伯克利套接字 API 不同?
Berkeley API 确实存在于 Windows 上(参见recv和 family),并且在很大程度上与任何其他 Berkeley Sockets 实现兼容。
有关将套接字代码移植到 Windows 的信息,请参阅 MSDN 文章“将套接字应用程序移植到 Winsock” 。
尝试使用ACE——它是一个很棒的跨平台通信库。
Milen 在评论中说,但Apache Portable Runtime库涵盖了网络应用程序的许多可移植性问题。