Boost::asio winsock 和 winsock 2 兼容性问题

Posted

技术标签:

【中文标题】Boost::asio winsock 和 winsock 2 兼容性问题【英文标题】:Boost::asio winsock and winsock 2 compatibility issue 【发布时间】:2012-04-02 18:26:02 【问题描述】:

我的项目使用 windows.h,其中使用了 winsock.h,我需要包含使用 winsock2 的 boost:assio。所以我收到很多错误,说 Winsock.h 已经包含在内。 我可以定义 WIN32_LEAN_AND_MEAN。这样windows.h就不会使用winsock。问题是,我需要 windows.h 才能使用它,而异步计时器只需要 Asio。我不需要它的 winsock2.h 。我尝试搜索如何禁用它的 winsock2 使用,我发现我可以通过在包含 boost:asio 之前定义 BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN 来做到这一点,但我仍然得到同样的错误。

#include <windows.h>
#define BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN
#include <boost/asio.hpp>

错误

1>c:\program files\boost\boost_1_47\boost\asio\detail\socket_types.hpp(22): 致命错误 C1189: #error : WinSock.h 已经包含

【问题讨论】:

【参考方案1】:

尝试更改包含的顺序。以boost/asio.hpp 开头,后面加上windows.h

通常任何代码库的编写者都会解决兼容性问题,但如果他们的代码首先满足编译器和预处理器,他们可以做得更好。

ACE 也有类似的问题,包括 ace/OS.h,然后才解决它。

【讨论】:

还有一个问题:一个应用程序是否可以从另一个应用程序读取带有 winsock2 的数据包,女巫发送带有 winsock1 的数据包?反之亦然。 @DainiusKreivys 我不确定从 winsock1 到 2 的更新是什么。我只能猜测它主要是错误修复。除了错误,一切都应该可以正常工作,但是由于可能存在错误,它们可能会出现。 更改包含的顺序并没有真正解决问题,只是将其从错误更改为警告。【参考方案2】:

正如 Danius(OP)指出的那样编译

#include <windows.h>
#include <boost/asio.hpp>

失败并出现此错误:

1>c:\source\<SNIP>\boost\1.51.0\boost\asio\detail\socket_types.hpp(22): fatal error C1189: #error :  WinSock.h has already been included

另一方面

#include <boost/asio.hpp>
#include <windows.h>

产生一堆噪音并错误设置Windows版本#

1?  Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:
1>  - add -D_WIN32_WINNT=0x0501 to the compiler command line; or
1>  - add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.
1>  Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).

我找不到任何不会留下不好味道的方法,但是:

#ifdef _WIN32
#  ifdef USE_ASIO
//     Set the proper SDK version before including boost/Asio
#      include <SDKDDKVer.h>
//     Note boost/ASIO includes Windows.h. 
#      include <boost/asio.hpp>
#   else //  USE_ASIO
#      include <Windows.h>
#   endif //  USE_ASIO
#else // _WIN32
#  ifdef USE_ASIO
#     include <boost/asio.hpp>
#  endif // USE_ASIO
#endif //_WIN32

确实会产生干净的编译。

应该没那么难社论>

【讨论】:

请说明“this”应该在哪里更改 把它放在一个头文件中,否则你可能会在包含头文件的 cpp 文件中包含 asio.hpp 和 windows.h 和 #define USE_ASIO。 #include &lt;SDKDDKVer.h&gt; 是最终帮助我克服这一切的缺失的想法。谢谢!【参考方案3】:

对我来说,切换包含的顺序会导致与我正在使用的另一个 Microsoft 包含的编译错误 - 使用“typedef 接口”声明事物。

由于我的错误来自 socket_types.h,因此来自以下几行:

# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
#  error WinSock.h has already been included
# endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)

我在windows.h之前加上了“winsock2.h”的include,最后是boost/asio.hpp include,然后就顺利编译了。

【讨论】:

【参考方案4】:
#ifdef BOOST_OS_WINDOWS
#define _WIN32_WINNT 0x0501
#if _WIN32_WINNT <= 0x0501
#define BOOST_ASIO_DISABLE_IOCP
#define BOOST_ASIO_ENABLE_CANCELIO
#endif
#endif

【讨论】:

通常被认为是解释您的建议/答案的好方法。即使在技术上是正确的,仅代码的答案也可能会令人惊讶地缺乏信息。【参考方案5】:

我使用的另一个解决方法是集中所有依赖于 asio 的 XXX.hpp 文件中的代码并将其包含在实现的每个窗口的顶部 XXX.cpp 文件,您可以在其中使用其对象。

此方法将包含 asio 置于任何其他包含 windows.h 之上并解决问题。

【讨论】:

以上是关于Boost::asio winsock 和 winsock 2 兼容性问题的主要内容,如果未能解决你的问题,请参考以下文章

Winsock 连接很慢

Boost.Asio Win32 Windows 应用程序

使用 Boost.Asio 和 OpenSSL 的 HTTPS 请求

Boost Asio async_send 产生哔声

使用 boost::asio::async_wait_until 和 boost::asio::streambuf

websocketpp 和 boost.asio 有啥区别?