当前位置: 首页 > news >正文

Zmq适配Win7 SP0 / Win XP/ Win 2k

1.目的

由于发布版本的libzmq使用了较多新的系统特性,导致在低版本windows平台上无法使用。
因此,需要对zmq源码进行修改以适配低版本的系统,如Win7 SP0,Win XP,Win2003等等。

2.Win7 SP0

#if defined ZMQ_HAVE_WINDOWS && defined WSA_FLAG_NO_HANDLE_INHERIT// if supported, create socket with WSA_FLAG_NO_HANDLE_INHERIT, such that// the race condition in making it non-inheritable later is avoidedconst fd_t s = WSASocket (domain_, type_, protocol_, NULL, 0,WSA_FLAG_OVERLAPPED|WSA_FLAG_NO_HANDLE_INHERIT);
#elseconst fd_t s = socket (domain_, type_, protocol_);
#endif

zmq在高版本系统上为了通信安全考虑,使用了WSA_FLAG_NO_HANDLE_INHERIT标志,但是由于WSA_FLAG_NO_HANDLE_INHERIT这个标志是从 Windows 7 with SP1, Windows Server 2008 R2 with SP1开始支持的,因此在Win7 SP0系统上会出现socket连接无法初始化的问题。

解决方法:
方案1:取消WSA_FLAG_NO_HANDLE_INHERIT标志的使用
方案2:参考Win XP

3.Win XP

由于Windows XP系统与现代操作系统差别较大,系统库差异较大,因此,需要对项目进行较大的变更。

1. 选择VS对应版本的工程文件

​ 以VS2013为例 :libzmq-4.3.4\builds\deprecated-msvc\vs2013\libzmq.sln

2. 选择支持XP系统的工具集

Windows XP (v120_xp)

3. 项目文件变更
文件名操作
src\channel.cpp新增
src\endpoint.cpp新增
src\ip_resolver.cpp新增
src\peer.cpp新增
src\raw_engine.cpp新增
src\stream_connecter_base.cpp新增
src\stream_engine_base.cpp新增
src\stream_listener_base.cpp新增
src\tweetnacl.c新增
src\v3_1_encoder.cpp新增
src\zmtp_engine.cpp新增
src\stream_engine.cpp删除
4. 预处理器定义

ZMQ_IOTHREAD_POLLER_USE_SELECT;
ZMQ_POLL_BASED_ON_SELECT;
ZMQ_HAVE_CURVE;
ZMQ_USE_TWEETNACL;

5. 代码兼容

1)ConditionVariable最低支持的客户端版本是Windows Vista,因此若支持C++11中的std::condition_variable_any,则可以使用ZMQ_USE_CV_IMPL_STL11定义规避此问题。否则,需要使用第三方库或者利用事件(event)或信号量(semaphore)来实现条件变量。

#include "windows.hpp"namespace zmq
{
class condition_variable_t
{public:inline condition_variable_t () { InitializeConditionVariable (&_cv); }inline int wait (mutex_t *mutex_, int timeout_){int rc = SleepConditionVariableCS (&_cv, mutex_->get_cs (), timeout_);if (rc != 0)return 0;rc = GetLastError ();if (rc != ERROR_TIMEOUT)win_assert (rc);errno = EAGAIN;return -1;}inline void broadcast () { WakeAllConditionVariable (&_cv); }private:CONDITION_VARIABLE _cv;ZMQ_NON_COPYABLE_NOR_MOVABLE (condition_variable_t)
};
}

2)if_indextoname最低支持的客户端版本是Windows Vista。因此,需要在XP上重新实现这个方法。

 #include <netioapi.h>static PCHAR WINAPI if_indextoname_custom (__in NET_IFINDEX InterfaceIndex,__out_ecount (IF_NAMESIZE)PCHAR InterfaceName)
{typedef PCHAR (WINAPI * fn_if_indextoname) (NET_IFINDEX InterfaceIndex,PCHAR InterfaceName);PCHAR ret = NULL;if (HMODULE hDll = LoadLibraryA ("Iphlpapi.dll")) {fn_if_indextoname _if_indextoname =(fn_if_indextoname) GetProcAddress (hDll, "if_indextoname");if (_if_indextoname)ret = _if_indextoname (InterfaceIndex, InterfaceName);FreeLibrary (hDll);}return ret;
}

4.Win2000

由于windows2000的版本过低,因此只能使用较低版本的开发工具VS2005。

1. 选择适当版本的VS工程文件

libzmq-4.3.4\builds\deprecated-msvc\vs2008\libzmq.sln

2. 工程文件变更
解决方案:
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
↓
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005工程文件:
<VisualStudioProject ProjectType="Visual C++" Version="9,00"
或者
<VisualStudioProject ProjectType="Visual C++" Version="9.00"
↓
<VisualStudioProject ProjectType="Visual C++" Version="8.00"编码:
UTF-8 BOM → ANSI换行符:
LF → CRLF
3. 步骤3/4与XP相同

省略

4. 代码兼容

1)ConditionVariable
与XP相同,省略
2)GetAdaptersAddresses
由于resolve_nic_name函数业务相关性较低,因此采用NOP方式规避。

    if (!resolved && _options.allow_nic_name ()) {//  Try to resolve the string as a NIC name.const int rc = -1; // resolve_nic_name (ip_addr_, addr_str);errno = ENODEV;//......}

3)getaddrinfo
虽然windows2000 原生不支持getaddrinfo函数,但是可以通过windows 2000 ipv6 预览版扩展系统功能,以支持getaddrinfo。

#include <ws2tcpip.h>
#include <wspiapi.h>  //在<ws2tcpip.h>后包含<wspiapi.h>
5. 安装windows 2000 ipv6 预览版
http://www.lryc.cn/news/125991.html

相关文章:

  • 掌握Python的X篇_30_使用python解析网页HTML
  • 广联达OA前台sql注入+后台文件上传漏洞复现分析
  • No view found for id 0x7f0901c3 for fragment解决以及线上bug排查技巧
  • 腾讯云CVM服务器竞价实例是什么?和按量计费有什么区别?
  • Kali Linux助您网络安全攻防实战
  • JavaEE初阶:多线程 - 编程
  • 一种多策略下RabbitMQ的延时队列实现
  • 解密 AI 客服;在不同硬件设备上运行大型语言模型的可能性
  • 问题:【IntelliJ IDEA】解决idea自动声明变量加finall修饰符问题
  • SpringBoot基于Zookeeper实现分布式锁
  • AT89C51单片机实现单片机串口互动(中断方式,单片机--单片机,应答)
  • 九耶丨阁瑞钛伦特-请说说你在工作中的PRD文档是如何撰写的?
  • Android免打包多渠道统计如何实现
  • Apipost CICD怎么配置?
  • utf-8和utf-8 mb4区别
  • 考研 408 | 【计算机网络】 应用层
  • 设计模式-单例
  • mysql截取最后一个字符之前的数据
  • Flutter 中,ListView 中需要放置 ListView 需要怎么处理才高效?
  • Appium Desktop安装
  • Open3D 最小二乘拟合平面(SVD分解法)
  • Pytorch源码搜索与分析
  • 运维监控学习笔记9
  • gulimall-缓存-缓存使用
  • 概述、搭建Redis服务器、部署LNP+Redis、创建Redis集群、连接集群、集群工作原理
  • redis数据类型与底层数据结构对应关系
  • SpringBoot请求响应
  • 功能上新|全新GPU性能优化方案
  • 试岗第一天问题
  • 2023-08-15力扣每日一题