├── .gitignore
├── README.md
├── curl_multi.sln
└── curl_multi
├── HttpTask.cpp
├── HttpTask.h
├── ReadMe.txt
├── Resource.h
├── SkyChaserHttp.cpp
├── SkyChaserHttp.h
├── SkyMultiHttp.cpp
├── SkyMultiHttp.h
├── curl_multi.h
├── curl_multi.rc
├── curl_multi.vcxproj
├── curl_multi.vcxproj.filters
├── libcurl
├── curl.h
├── curlbuild.h
├── curlrules.h
├── curlver.h
├── easy.h
├── lib
│ ├── libcurl.lib
│ ├── libcurld.lib
│ ├── libeay32.lib
│ ├── libeay32d.lib
│ ├── ssleay32.lib
│ ├── ssleay32d.lib
│ ├── zlib.lib
│ └── zlibd.lib
├── mprintf.h
├── multi.h
├── stdcheaders.h
├── typecheck-gcc.h
└── zlib
│ ├── zconf.h
│ └── zlib.h
├── libuv
├── include
│ ├── android-ifaddrs.h
│ ├── pthread-barrier.h
│ ├── stdint-msvc2008.h
│ ├── tree.h
│ ├── uv-aix.h
│ ├── uv-bsd.h
│ ├── uv-darwin.h
│ ├── uv-errno.h
│ ├── uv-linux.h
│ ├── uv-os390.h
│ ├── uv-posix.h
│ ├── uv-sunos.h
│ ├── uv-threadpool.h
│ ├── uv-unix.h
│ ├── uv-version.h
│ ├── uv-win.h
│ └── uv.h
└── lib
│ └── libuv.lib
├── main.cpp
├── scCookie.txt
├── stdafx.cpp
├── stdafx.h
├── targetver.h
├── test.cpp
├── use_curl_multi.cpp
└── use_curl_multi.h
/.gitignore:
--------------------------------------------------------------------------------
1 | *.[oa]
2 | *.~
3 | *.swp
4 | *.out
5 | *.in
6 | *.o
7 |
8 | #################
9 | ## Eclipse
10 | #################
11 |
12 | *.pydevproject
13 | .project
14 | .metadata
15 | bin/
16 | tmp/
17 | *.tmp
18 | *.bak
19 | *.swp
20 | *~.nib
21 | local.properties
22 | .classpath
23 | .settings/
24 | .loadpath
25 |
26 | # External tool builders
27 | .externalToolBuilders/
28 |
29 | # Locally stored "Eclipse launch configurations"
30 | *.launch
31 |
32 | # CDT-specific
33 | .cproject
34 |
35 | # PDT-specific
36 | .buildpath
37 |
38 |
39 | #################
40 | ## Visual Studio
41 | #################
42 |
43 | ## Ignore Visual Studio temporary files, build results, and
44 | ## files generated by popular Visual Studio add-ons.
45 |
46 | # User-specific files
47 | *.suo
48 | *.user
49 | *.sln.docstates
50 |
51 | # Build results
52 | [Dd]ebug/
53 | [Rr]elease/
54 | *_i.c
55 | *_p.c
56 | *.ilk
57 | *.meta
58 | *.obj
59 | *.pch
60 | *.pdb
61 | *.pgc
62 | *.pgd
63 | *.rsp
64 | *.sbr
65 | *.tlb
66 | *.tli
67 | *.tlh
68 | *.tmp
69 | *.vspscc
70 | .builds
71 | *.dotCover
72 |
73 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
74 | #packages/
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opensdf
81 | *.sdf
82 |
83 | # Visual Studio profiler
84 | *.psess
85 | *.vsp
86 |
87 | # ReSharper is a .NET coding add-in
88 | _ReSharper*
89 |
90 | # Installshield output folder
91 | [Ee]xpress
92 |
93 | # DocProject is a documentation generator add-in
94 | DocProject/buildhelp/
95 | DocProject/Help/*.HxT
96 | DocProject/Help/*.HxC
97 | DocProject/Help/*.hhc
98 | DocProject/Help/*.hhk
99 | DocProject/Help/*.hhp
100 | DocProject/Help/Html2
101 | DocProject/Help/html
102 |
103 | # Click-Once directory
104 | publish
105 |
106 | # Others
107 | [Bb]in
108 | [Oo]bj
109 | sql
110 | TestResults
111 | *.Cache
112 | ClientBin
113 | stylecop.*
114 | ~$*
115 | *.dbmdl
116 | Generated_Code #added for RIA/Silverlight projects
117 |
118 | # Backup & report files from converting an old project file to a newer
119 | # Visual Studio version. Backup files are not needed, because we have git ;-)
120 | _UpgradeReport_Files/
121 | Backup*/
122 | UpgradeLog*.XML
123 |
124 |
125 |
126 | ############
127 | ## Windows
128 | ############
129 |
130 | # Windows image file caches
131 | Thumbs.db
132 |
133 | # Folder config file
134 | Desktop.ini
135 |
136 |
137 | #############
138 | ## Python
139 | #############
140 |
141 | *.py[co]
142 |
143 | # Packages
144 | *.egg
145 | *.egg-info
146 | dist
147 | build
148 | eggs
149 | parts
150 | bin
151 | var
152 | sdist
153 | develop-eggs
154 | .installed.cfg
155 |
156 | # Installer logs
157 | pip-log.txt
158 |
159 | # Unit test / coverage reports
160 | .coverage
161 | .tox
162 |
163 | #Translations
164 | *.mo
165 |
166 | #Mr Developer
167 | .mr.developer.cfg
168 |
169 | # Mac crap
170 | .DS_Store
171 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 封装libcurl+libuv实现multi异步高效http请求
2 |
3 |
4 | > 关于libcurl+libuv实现异步http请求的简单例子可以参考:http://blog.csdn.net/lijinqi1987/article/details/53996129
开发环境:win7, vs2013
5 |
6 |
7 |
8 | ## libuv使用流程
9 |
10 | > 主要参考上面文章中的代码
11 |
12 | 1. 获取默认事件循环句柄`uv_loop_t loop = uv_default_loop();`
13 |
14 | 2. 初始化定时器`uv_timer_init(loop, &timeout);`
15 |
16 | 3. 设置回调函数
17 |
18 | 4. 开始循环`uv_run(loop, UV_RUN_DEFAULT);`
19 |
20 | ## libuv和libcurl的mutil接口结合
21 |
22 | > 主要参考上面文章中的代码
23 |
24 | 1. 获得`curl multi`句柄`curl_handle = curl_multi_init();`
25 |
26 | 2. 设置回调
27 |
28 | ```cpp
29 | //调用handle_socket回调函数,传入新建的sockfd,根据传入的action状态添加到相应的事件管理器,如封装epoll的libev或libevent。
30 | curl_multi_setopt(curl_handle, CURLMOPT_SOCKETFUNCTION, handle_socket);
31 | /*当使用curl_multi_add_handle(g->multi, conn->easy)添加请求时会回调start_timeout,然后调用
32 | curl_multi_socket_action(curl_handle, CURL_SOCKET_TIMEOUT, 0, &running_handles)初始化请求并得到一个socket(fd)*/
33 | curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, start_timeout);
34 | ```
35 |
36 | 3. 循环结束后清理环境`curl_multi_cleanup(curl_handle);`
37 |
38 |
39 | ## 封装
40 |
41 | 1. 对于`curl multi`接口的http请求而言,除了不是主动请求,其他使用方式和`easy`接口完全一致,因此根据需要修改了以前的`CSkyChaserHttp`类,仅为构造增加了一个默认参,在使用`multi`接口时不主动进行http请求
42 |
43 | 2. 对于`libuv`和`libcurl`配合使用的部分,由于除了完成请求后的回调需要自己控制,其他的都是固定的套路,因此封装了一个`CSkyMultiHttp`类,在构造时将回调函数传进去,然后调用`Init()`方法来初始化,然后通过`curl_multi_add_handle(CSkyMultiHttp::m_curl_handle, http_curl_handle);`来添加事件,最后通过`loop()`方法来开始事件循环
44 |
45 | 3. 最后再封装了一个`CHttpTask`类,用来管理所有的`http_curl_handle`和任务事件,从而实现连续的http请求动作,通过`AddTask()`方法来添加最初的事件任务,再通过`TaskDoneProc(...)`方法来处理一个请求完成后的动作,主要是添加下一个请求到事件循环中
46 |
47 | ## 效果
48 |
49 | 对一个小型网站进行注册测试:
50 |
51 | - 开1000个并发连接,一共1万×5次请求(不包括30X重定向产生的请求),速度局限于对方服务器和网速,显得比较慢,而且这么多并发,直接导致对方服务器无响应了,失败几率很高,并且在测试期间,通过浏览器很难访问这个网站,而本机CPU占用率很低,在这种情况下无法测出性能的极限
52 |
53 | ## vs2013环境下编译libuv
54 |
55 | [https://kevins.pro/bulid_libuv_with_vs2013.html](https://kevins.pro/bulid_libuv_with_vs2013.html)
--------------------------------------------------------------------------------
/curl_multi.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.40629.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "curl_multi", "curl_multi\curl_multi.vcxproj", "{EAF8BFB2-40D3-4C91-80CF-8E9F03703555}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {EAF8BFB2-40D3-4C91-80CF-8E9F03703555}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {EAF8BFB2-40D3-4C91-80CF-8E9F03703555}.Debug|Win32.Build.0 = Debug|Win32
16 | {EAF8BFB2-40D3-4C91-80CF-8E9F03703555}.Release|Win32.ActiveCfg = Release|Win32
17 | {EAF8BFB2-40D3-4C91-80CF-8E9F03703555}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/curl_multi/HttpTask.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KevinsBobo/curl_multi/c35cbdbb25cd6abbe34d6fc610e3f31d36b01443/curl_multi/HttpTask.cpp
--------------------------------------------------------------------------------
/curl_multi/HttpTask.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "SkyMultiHttp.h"
3 | #include
4 | #include