微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在网络库中初始化Winsock的最佳实践

如何解决在网络库中初始化Winsock的最佳实践

我正在编写一个小的库,该库在内部使用OS套接字API进行一些联网。

在Windows上,需要通过在开始时调用WSAStartup在结束时调用WSACleanup来初始化Winsock。但是documentation表示允许多次初始化Winsock,然后清除相同的次数,因为它在内部使用引用计数。

现在我正在解决一个难题。什么是图书馆作家更好的做法?

  1. 提供全局函数initializeLibrary / terminateLibrary,这些全局函数调用WSAStartup / WSACleanup并指示用户在其应用程序的开始/结束处对其进行调用
  2. 在我的类的构造函数/析构函数中内部调用WSAStartup / WSACleanup,根本不要打扰用户

现在我看到第二个选项看起来更方便,但这是一个好主意吗?这样做没有任何潜在的不良后果吗?会对性能产生影响吗?图书馆秘密地这样做是一种好习惯吗?

解决方法

图书馆秘密地这样做是一种好习惯吗?

我在这里可能遗漏了要点,但对我而言,任何库的要点是将详细信息从最终用户那里分离出来,从而使使用起来毫无麻烦。当然,抽象可能会在一定程度上限制灵活性,但是我不觉得这是事实。请注意,我只解决“保密”问题,老实说,我不知道它如何影响e。 G。性能。

什么是图书馆作家更好的做法?

您在这里缺少第三个选项。我通常反对init()finalize()函数,因为它违反了RAII-用户可能会简单地忘记调用这些函数。但是,您可以设计一个“令牌”类,该类仅在应用程序的“根”创建,这是使用API​​的任何其他部分所必需的。考虑一下:

#include <WinSock2.h>

class ApiKey {
public:
    ApiKey() {
        auto wsadata = WSADATA();
        auto startupResult = WSAStartup(MAKEWORD(2,2),&wsadata);
        // ...
    }

    ~ApiKey() {
        auto cleanupResult = WSACleanup();
        // ...
    }
};

class Socket {
public:
    Socket(ApiKey& key) {
    }
    // ...
};

我不是boost :: asio用户,但据我所知,这就是他们的方式。 io_context类用作ApiKey

如果需要更多信息,可以在他们的源代码中查找:

https://github.com/boostorg/asio/blob/develop/include/boost/asio/detail/impl/winsock_init.ipp

https://github.com/boostorg/asio/blob/develop/include/boost/asio/io_context.hpp

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。