【问题标题】:Winsock 2 portabilityWinsock 2 可移植性
【发布时间】:2009-05-06 13:42:02
【问题描述】:

我即将在 C++ 中开发一些与套接字相关的东西,并且希望该软件从一开始就尽可能地在 Windows 和 Linux 之间移植(让它以后移植很棘手。)

我查看了不同的库,有一个来自alhem.net 的 C++ 库,当然还有 boost::asio。 boost::asio 看起来很有前途,但对于这么小的应用程序来说将是一个非常大的依赖项。

是否值得自己编写这些东西,还是应该只使用库?如果我自己做,主要的陷阱是什么?

【问题讨论】:

    标签: c++ winsock portability


    【解决方案1】:

    我开发了一些围绕套接字的便携式包装器。确保您不会走下由 WinSock2 事件构成的糟糕的不归路。除此之外,在我看来,最大的区别是:

    • 在Windows中启动联网,需要调用::WSAStartup(),在Windows中关闭,运行::WSACleanup();在 Linux 中什么都不做,
    • close() 在 Linux 中是 closesocket() 在 Windows 中,
    • 默认缓冲区大小因驱动程序和操作系统而异,因此请务必使用SO_RCVBUFSO_SNDBUF 进行设置,
    • SO_REUSEADDR 在 Windows 上窃取地址,允许在 Linux 上频繁重新打开;你可能只想在 Linux 中使用这个标志,
    • 在 Windows 中使用 ::ioctlsocket(),在 Linux 中使用 ::fcntl(),使套接字成为非阻塞,
    • 头文件不同,<sys/socket.h> 和朋友在 Linux 中,<WinSock.h> 在 Windows 中,
    • 要便携,最简单的方法可能是使用::select() 等待数据到达,
    • fd_sets 在 Windows/Linux 上完全不同;这仅在您需要优化 fd_sets 的初始化时才相关,例如在添加/删除任意套接字时,
    • 在 Windows 中,当套接字关闭时,挂在套接字上的任何线程都会被释放并带有错误代码,在 Linux 中,线程保持等待。如果线程阻塞了套接字,例如::recvfrom(),您可以考虑使用::sendto() 来释放Linux 下的停止线程。

    我曾经需要的所有其他东西都是从 låda 中解决的。

    【讨论】:

    • 非常有用的建议。 Tackar och bugar ;)。
    【解决方案2】:

    Winsocks 与 Posix 套接字不太兼容:

    • 在 Winsocks 中,套接字的类型为 SOCKET。在 Posix 上,它只是一个文件描述符 (int),您可以在其上执行正常的 read()write() 调用。
    • 它们返回错误的方式不同。
    • 他们不支持recv()send() 上的某些选项。
    • 您必须使用两个特殊函数初始化和统一 Winsocks 库。
    • 我认为您不能使用shutdown()close() 关闭Windows 套接字。它类似于 closesocket()

    肯定有更多的不同,但这是我现在能记住的。如果您希望 Winsocks 具有可移植性,您将拥有一个用于关闭套接字、打印错误消息等的小型库。

    我个人可能会选择boost::asio(不过我从未使用过它)。

    【讨论】:

    • 好的,我会看看我该怎么做。 boost::asio 也有一个非常好的 ICMP 接口,所以目前看来我会使用它。
    • shutdown() 是 Windows 套接字的有效函数。不过,您是否正确认为需要使用 closesocket()。
    • closesocket 只是windows 版本的close——因此它们不必重载close 函数。您不必关闭文件/套接字,但如果您不这样做,您可能会丢失数据。 WSAGetLastError 只是获取errno 的windows 函数,因为windows API 并不以同样的方式支持errno。对于套接字,POSIX 支持“发送”和“接收”版本的读写。
    【解决方案3】:

    看看“自适应通信环境”(ACE) 库: (ACE Home Page) 它提供了一些很好的抽象和很大的灵活性,所有这些都集中在一个支持 Windows、MacOS 和 Linux 的可移植库中。 它的学习曲线有点陡峭,但我从中获得了非常好的价值。

    【讨论】:

      【解决方案4】:

      您将使用多少套接字?我已经完成了几个应用程序,其中套接字的东西非常高级(打开、读取、写入),并且从 Windows 到 Linux 都可以完美运行。如果不止于此 - 使用 boost。

      【讨论】:

      • 一开始是非常低级的,比如打开连接、写东西、读、退出。不过,它可能会增长到包含 Http-stuff。
      【解决方案5】:

      老实说,我会优先使用 boost::asio。如果你真的想对套接字 API 感到厌烦,你可以在 Windows 和 Linux 上使用标准的 BSD 风格的套接字 API——只是在 Windows 上你必须链接到(并初始化)Winsock2,而在Linux 你不会有一个单独的库来链接。

      【讨论】:

        【解决方案6】:

        【讨论】:

        • 似乎很有用。谢了哥们。不过它似乎很旧,最后一次更新是 2003 年?但也许它仍然运作良好。
        猜你喜欢
        • 2013-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-04
        • 2013-08-01
        相关资源
        最近更新 更多