多线程下载加速器控制台






4.94/5 (5投票s)
将 Linux 和其他 Unix 的轻量级下载加速器 Axel 移植到 NATIVE WIN32
引言
Axel 是一个轻量级的 Linux 和其他 Unix 系统的下载加速器。它应该可以在 BSD、Solaris、Darwin (Mac OS X) 和 Win32 (Cygwin) 系统上编译和运行。
移植到原生 WIN32,无需 Cygwin,例如我在 #if WIN32 #endif
中所做的工作
- 将 Linux 文件描述符用于新的套接字,更改为 WIN32
SOCKET
描述符,引用新的套接字 - 将
close
、write
、read
更改为closesocket
、send
、recv
- 将
select
阻塞线程更改为WSAEventSelect
异步 I/O - 将线程的
pthread_t
更改为引用线程的HANDLE
- 将
pthread_create
、pthread_join
、pthread_cancel
更改为CreateThread
、WaitForSingleObject
、TerminateThread
- 将 Linux 文件描述符用于保存文件,更改为引用保存状态的
HANDLE
- 将
open
、read
、write
、close
更改为CreateFile
、ReadFile
、WriteFile
、CloseHandle
背景
调试 Axel 以查看多线程下载方式
- TCP 连接(
socket
、bind
、connect
)到主机,例如由 IIS 提供的 https:// - 发送 HTTP 头部请求
GET / HTTP/1.0 Host: www.codeproject.com Range: bytes=1- User-Agent: Axel 2.4 (WIN32)
- 从头部回复中获取内容长度
HTTP/1.1 206 Partial Content Content-Type: text/html Last-Modified: Tue, 20 Sep 2011 03:39:05 GMT Accept-Ranges: bytes ETag: "3c2bb1d84677cc1:0" Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET Date: Fri, 24 Feb 2012 08:41:12 GMT Connection: close Content-Length: 688 /* Here is what I need */ Content-Range: bytes 1-688/689
- 将内容范围划分为线程数,例如 10
Downloading 0-67 using conn. 0 Downloading 68-136 using conn. 1 Downloading 137-205 using conn. 2 Downloading 206-274 using conn. 3 Downloading 275-343 using conn. 4 Downloading 344-412 using conn. 5 Downloading 413-481 using conn. 6 Downloading 482-550 using conn. 7 Downloading 551-619 using conn. 8 Downloading 620-688 using conn. 9
- 通过其中一个线程发送带有范围 [from, to] 的 HTTP 头部请求
GET / HTTP/1.0 Host: localhost Range: bytes=206-274 User-Agent: Axel 2.4 (WIN32)
从 SOCKET
接收 recv
缓冲区,将 HTTP 头部回复中的缓冲区写入 HANDLE
CreateFile
,使用临时文件 *.st(Axel 风格),下载内容范围后终止并关闭线程。临时文件有助于服务器主机恢复可用性。
Using the Code
源代码文件 text.c 是主入口,可以被视为一个很好的示例和测试用例,说明如何使用 Axel API。
conf_t conf;
conf_init(&conf);
conf.num_connections = 10; /* multi-thread numbers */
conf.add_header_count = 0;
/* axel_t object construct */
axel_t *axel = axel_new(&conf, 0, "https://");
strcpy(axel->filename, "filename.htm");
axel_open(axel);
axel_start(axel);
/* Have not downloaded the total content */
while (!axel->ready)
{
axel_do(axel);
/* printf some verbose about download threads info such as speed and complete percent */
}
/* axel_t object destruct */
axel_close(axel);
关注点
跨平台开发 - 在 Gentoo Linux 下使用 Axel 控制台来查看多线程下载加速器的工作方式,然后使用原生 WIN32 API 移植到 Windows。我在 Windows 7 64 位下使用 VS2005 编译源代码(选择 mbstring
项目设置,而不是 Unicode,这会导致 ^M CTRL-V CTRL-M、无法识别的中文字符和二进制文件垃圾问题),因此需要更多的贡献者在其他 Windows 发行版下进行调试。
改进
Windows Vista、7 和 Server 2008 才支持 WSAPoll
,用于确定一个或多个套接字的的状态。它可能比 WSAEventSelect
更有效。
历史
- 2012-02-27 xzhai 无 BUG :)
- 2012-02-26 xzhai
- 修复了重新连接的错误
- 修复了 BIGSIZE 文件冻结的错误
- 2012-02-24 xzhai
- 将 Axel v2.4 移植到无需 Cygwin 的 WIN32