最近做了一个多线程下HTTP get请求,莫名其妙的异常,不是无法连接主机,就是崩溃。官方给的是curl是线程安全的,但其实用的时候就感觉很多问题,官方给的方案是 带c-ares 的curl。
1 下载curl URL:https://curl.haxx.se
解压 ,在解压目录下curl-7.47.1\winbuild 打开BUILD.WINDOWS.txt 看下文档里面的说明,然后看下 MakeFileBuild.vc 从这个文件里 大概能了解到基本要关联的库
命令:(BUILD.WINDOWS.txt 里面的)
nmake /f Makefile.vc mode=
where
VC=<6,7,8,9,10,11,12,14> - VC versions
WITH_DEVEL=
- Paths for the development files (SSL, zlib, etc.) Defaults to sibbling directory deps: ../deps
Libraries can be fetched at http://windows.php.net/downloads/php-sdk/deps/
Uncompress them into the deps folder.
WITH_SSL=
- Enable OpenSSL support, DLL or static WITH_CARES=
- Enable c-ares support, DLL or static WITH_ZLIB=
- Enable zlib support, DLL or static WITH_SSH2=
- Enable libSSH2 support, DLL or static ENABLE_SSPI=
- Enable SSPI support, defaults to yes ENABLE_IPV6=
- Enable IPv6, defaults to yes ENABLE_IDN=
- Enable use of Windows IDN APIs, defaults to yes Requires Windows Vista or later, or installation from:
https://www.microsoft.com/downloads/details.aspx?FamilyID=AD6158D7-DDBA-416A-9109-07607425A815
ENABLE_WINSSL=
- Enable native Windows SSL support, defaults to yes GEN_PDB=
- Generate Program Database (debug symbols for release build) DEBUG=
- Debug builds MACHINE=
- Target architecture (default is x86)
我想要 WITH_SSL WITH_CARES WITH_ZLIB 编译进去
2 下载c-ares URL:http://c-ares.haxx.se/
相对路径:c-ares-1.10.0\vc下有工程文件,用vs2008打开就可以,编译一下
3 下载openssl URL:https://www.openssl.org/
自己编译
4 下载zlib 自己编译
上面工作 准备好了就可以了
编译curl
1 还是看build.windows.txt文件:如下:
If you wish to support zlib, openssl, c-ares, ssh2, you will have to download
them separately and copy them to the deps directory as shown below:
somedirectory\
|_curl-src
| |_winbuild
|
|_deps
|_ lib
|_ include
|_ bin
这是目录结构,你把c-ares openssl zlib的相关头文件 lib dll放到相应的文件就可以了
2 修改了MakefileBuild.vc
找到SSL_LIBS 在后面添加cares.lib
3 修改curl-7.26.0\lib\config-win32.h
找到 如下 看注释 默认是开启线程异步DNS查找,所以修改成:
/* ---------------------------------------------------------------- */
/* DNS RESOLVER SPECIALTY */
/* ---------------------------------------------------------------- */
/*
* Undefine both USE_ARES and USE_THREADS_WIN32 for synchronous DNS.
*/
/* Define to enable c-ares asynchronous DNS lookups. */
#define USE_ARES 1 //这里注释去掉
/* Default define to enable threaded asynchronous DNS lookups. */
#if !defined(USE_SYNC_DNS) && !defined(USE_ARES) && \
!defined(USE_THREADS_WIN32)
/*# define USE_THREADS_WIN32 1*/ //可注可不注
#endif
#if defined(USE_ARES) && defined(USE_THREADS_WIN32)
# error "Only one DNS lookup specialty may be defined at most"
#endif
4 打开vs2008的命令行:
输入:nmake -f Makefile.vc mode=dll DEBUG=no VC=9 WITH_SSL=dll WITH_ZLIB=dll USE_IDN=no USE_SSSPI=yes USE_IPV6=yes GEN_PDB=yes
注:如果使用USE_IDN ,文档里说:
ENABLE_IDN=
Requires Windows Vista or later, or installation from:
https://www.microsoft.com/downloads/details.aspx?FamilyID=AD6158D7-DDBA-416A-9109-07607425A815
需要安装这个。不然编译时编不过。
截止目前没有做过测试,还不知道能用不,但会有问题,因为openssl.要线程安全必须设置回调,可以参考
openssl工程下openssl\crypto\threads\mttest.c
参考:
https://www.openssl.org/docs/man1.0.1/crypto/CRYPTO_set_locking_callback.html
https://curl.haxx.se/libcurl/c/threaded-ssl.html
https://curl.haxx.se/libcurl/c/opensslthreadlock.html