如何解决在网络库中初始化Winsock的最佳实践
我正在编写一个小的库,该库在内部使用OS套接字API进行一些联网。
在Windows上,需要通过在开始时调用WSAStartup
在结束时调用WSACleanup
来初始化Winsock。但是documentation表示允许多次初始化Winsock,然后清除相同的次数,因为它在内部使用引用计数。
- 提供全局函数
initializeLibrary
/terminateLibrary
,这些全局函数调用WSAStartup
/WSACleanup
并指示用户在其应用程序的开始/结束处对其进行调用。 - 在我的类的构造函数/析构函数中内部调用
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 举报,一经查实,本站将立刻删除。