免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: duanjigang
打印 上一主题 下一主题

源码阅读第一期:axel和wget [复制链接]

论坛徽章:
0
211 [报告]
发表于 2011-10-14 09:56 |只看该作者
总结:
现在才看出来远来真正函数入口地址在main.c 中。呵呵,谢谢版主的提醒,我原来还老觉得怎么真么少。
  我先说一下总体流程:wget程序实在是不小,应该是考虑很周密的原因。和其他程序一开始一样,都是要经过初始化的(在/src目录下也有其他的有main()入口,那是测试使用的,一般在上面都有这样类似的预定义:
35 #ifndef TESTING
36 #error "TESTING not set!!!"
37 #endif
)。
初始化:1、包括字符集的初始化;

2、程序一些默认参数的初始化;

3、对所能是使用命令行的初始化;

4、前面的单独的getopt_long是在用户选项之前找到注册文件,并解析;如果没有注册,那么就初始化;

5、后面的get_long是根据用户选项来设置命令,比如一个长选项 accept ,它会在前面加上—accept,然后这里是个解析用分隔符分开的元素,
用n个数组来指向有n-1 ','分隔符的字符串,然活用来分别设置。

6、下面是全部进行对初始化的options进行检查,必要的就设置,出错就打印错误;

7、下面是对sock_init(),因为下面会使用网络,先进行初始化;

8、如果详细监视opt.verbose的话,初始化一些程序起监督作用。

9、后面就是检查采用的什么类型的协议,比如ftp,或者http,然后从新写成http:// xxx. xxx.xxx.xxx格式,并保存在一个url数组里。

10、初始化日志文件。

11、初始化虚拟文件系统作为输出的目的地(如果VMS被定义)

12、设置信号量比如如果定义信号SIGNUP,那么就初始化这个信号函数,这是将输出信息打印到logfile中的重定向。

13、设置url及其接受到文件内容编码格式。

14、将url解析成 路径(path),端口(port),(主机名)(host),请求参数(query)等。

15、检索url地址,并用函数gethostbyname取得servent结构,通过函数retrive_url-> . . .-> gethttp()这里就是网路连接。其他类似。

17、最后选择是装载cookies.

18、打印失败的连接。

19、记录时间,并销毁计时器。

20、最后是清除前面分配东西,如果#ifdef DEBUG_MALLOC

评分

参与人数 1可用积分 +5 收起 理由
duanjigang + 5 谢谢分享

查看全部评分

论坛徽章:
0
212 [报告]
发表于 2011-10-14 14:29 |只看该作者
本帖最后由 雨过白鹭洲 于 2011-10-14 14:40 编辑

回复 207# xbjpkpk


    http://bbs.chinaunix.net/thread-3600933-5-1.html

你看下我48楼的贴子,三个项目都能开启调试功能的

论坛徽章:
0
213 [报告]
发表于 2011-10-14 16:45 |只看该作者
本帖最后由 雨过白鹭洲 于 2011-10-14 16:47 编辑

CU源码阅读2: curl总体了解


虽然咱们要做的是源码阅读,但是我个人在阅读开源项目的代码时,一般不会直接就钻进代码深处去研究,而是按下面步骤来:
1. 首先看看相关的文档,对项目有个大致了解
2. 编译运行程序,输入各种参数来了解程序的使用
3. 梳理整个项目的目录、源码结构,并大致了解各个目录和文件的作用
4. 找到main函数,开始跟着程序的流程快速地走一遍
5. 深入地分析、理解代码,并对自己感兴趣,或者需要解决问题的地方重点关注

-------------------------------------------华丽的分隔线-------------------------------------------
老实说,我并没有用过curl这个工具,在我需要下载的时候,通常都是交给迅雷不及掩耳盗铃这个强大而又流氓的软件来完成,当然这是在windows下。当我在Linux下需要下载东西时,通常都是直接使用Chrome的下载功能,偶尔还用过wget这个东东,不过总体来说,速度是没法跟迅雷相提并论的。

libcurl库是curl工具的核心,而对于广泛使用的libcurl库,我也从来没有在自己的项目中使用过。究其原因,主要是我水平不行,没有写过什么大型的网络项目。

因此,我自身的开发水平,特别是网络编程方面,无论是开发功底还是开发经验,其实都不是很强的。要分析透curl和libcurl,恐怕不是一件容易的事情,很多方面也不可能分析得特别深入。不过我倒是希望这一路分析下来,也能够让我在网络编程方面能够进步一些。
-------------------------------------------华丽的分隔线-------------------------------------------

好吧,废话不多说,下面就让我们来看看从curl网站上的文档中能够获取到什么有用的信息

我们使用和分析的是curl 7.22.0稳定版本,curl的全名是"Client for URLs",也就是URL客户端。curl项目实际上由curl命令行工具、和libcurl库组成。

下面是网站上的官方解释:
[curl]
curl是一个命令行工具,用于传输URL数据。支持的协议包括DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET, TFTP。

curl支持SSL证书、HTTP POST、HTTP PUT、FTP上传、HTTP基于form的上传、代理、cookies、用户+密码验证(基础、摘要、NTLM、Negotiate、kerberos等等)、文件重传、代理隧道,和其它很多有用的功能。

[libcurl]
libcurl是一个易于使用的客户端URL传输库。支持DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP等协议。

libcurl也支持SSL证书、HTTP POST、HTTP PUT、FTP上传、HTTP基于form的上传、代理、cookies、用户+密码验证(基础、摘要、NTLM、Negotiate、kerberos等等)、文件重传、代理隧道,和其它很多有用的功能

libcurl高度可移植,支持的平台包括:Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOs, Mac OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS, Symbian, OSF, Android, Minix, IBM TPF等等。

libcurl免费自由、线程安全、兼容IPv6、特性丰富、快速、社区支持


这里可以看到curl和其它下载工具的特性对比:
http://curl.haxx.se/docs/comparison-table.html
-------------------------------------------华丽的分隔线-------------------------------------------

下面我们来配置和编译curl 7.22.0

curl的配置项太多,一下子咱也看不过来,先不管那么多了,只把调试功能开启就拉倒了。

标准的三步曲:
./configure --enable-debug --disable-optimize --enable-curldebug
make
make install
默认安装到/usr/local/bin/curl

curl命令的基本用法:
curl [options] [URL...]
选项和参数是可选的,但是至少要提供一个URL,当然也可以同时指定多个

为了感受一下curl的复杂度,你还是自己运行一下
./curl --help
看看curl吓人的参数和选项

-------------------------------------------华丽的分隔线-------------------------------------------
好,下面我们来体验一下curl的使用

获得netscape web服务器的主页内容,直接打印输出
curl http://www.netscape.com/

来个ftp文件,也是直接输出
curl ftp://ftp.funet.fi/README

试试IPv6
curl -g "http://[2001:1890:1112:1::20]/"

下载到文件
curl -o thatpage.html http://www.netscape.com/
curl -O www.haxx.se/index.html -O curl.haxx.se/download.html

使用用户和密码下载ftp
curl ftp://name:passwd@machine.domain:port/full/path/to/file
curl -u name:passwd ftp://machine.domain:port/full/path/to/file

代理
curl -x my-proxy:888 ftp://ftp.leachsite.com/README

HTTP字节范围
curl -r 0-99 http://www.get.this/
curl -r -500 http://www.get.this/

上传
curl -T - ftp://ftp.upload.com/myfile
curl -T uploadfile -u user:passwd ftp://ftp.upload.com/myfile
curl -T uploadfile -u user:passwd ftp://ftp.upload.com/
curl -T localfile -a ftp://ftp.upload.com/remotefile

详细输出/调试
curl -v ftp://ftp.upload.com/
curl --trace trace.txt www.haxx.se

还有好多好多用法,今天就先到这里吧。等咱们分析到具体的功能时,再使用命令和参数来体验
-------------------------------------------华丽的分隔线-------------------------------------------

下一篇我们将查看curl项目的目录结构,以及主要目录和文件的作用。

评分

参与人数 1可用积分 +5 收起 理由
duanjigang + 5 支持!

查看全部评分

论坛徽章:
0
214 [报告]
发表于 2011-10-14 16:49 |只看该作者
这几天比较忙,没怎么上网。

看你们都快分析完了,这下恐怕来不及了

论坛徽章:
0
215 [报告]
发表于 2011-10-14 18:00 |只看该作者
回复 213# 雨过白鹭洲


    加油!!

论坛徽章:
0
216 [报告]
发表于 2011-10-17 09:13 |只看该作者
回复 124# wangzhen11aaa


    你好,你正在阅读的时哪一个的源代码啊?

论坛徽章:
0
217 [报告]
发表于 2011-10-17 11:55 |只看该作者
回复 215# 向前走直到永远
wget。我分析完了。

论坛徽章:
0
218 [报告]
发表于 2011-10-17 12:06 |只看该作者
CU源码阅读3: curl源码目录结构分析

说来惭愧,兄弟我以前写UNIX/Linux项目的时候,基本上是拿个Makefile模板,在上面改改改,完了就直接make。这里向大家推荐一个C/C++通用Makefile:http://www.javaeye.com/topic/774919 谁用谁知道!

因此我几乎没用过autoconf, automake, cmake等广泛使用的工具,对于大型项目如何使用这些工具来实现自动化构建和自动化测试,也不甚清楚。这一块将来还是得拿几个项目来实践实践,提升下使用相关工具的基本功。

但是优秀、成熟的开源项目,不可能采用这么原始的项目构建机制,curl也不例外。从curl的项目结构来看,主要应该是使用autoconf和automake来完成项目的构建,至少在基于UNIX的平台是这样。在Windows上,则使用了cmake来生成几个VC的项目文件(vc6curl.dsw、vc6curlsrc.dsw、vc6libcurl.dsw)。

至于是采用cmake来生成autoconf和automake的配置文件,还是开发者手工编写,我就不得而知了。总之咱们这一次的主要目的是阅读curl项目的源码,学习人家如何实现libcurl和curl,因此就不深究项目的构建和测试管理了。

下面是使用tree命令列出的curl-7.22.0主要目录:

  1. curl-7.22.0
  2. ├── CMake                                                  # CMake文件
  3. │   └── Platforms                                        # 平台相关的CMake文件
  4. ├── docs                                                     # 文档和示例代码
  5. │   ├── examples                                        # 主要是libcurl的使用示例代码
  6. │   └── libcurl                                             # libcurl的原始文档,用于生成可读格式的文档
  7. ├── include                                                  # 头文件
  8. │   └── curl
  9. ├── lib                                                         # libcurl的源码
  10. ├── m4                                                        # autoconf需要的GNU M4文件
  11. ├── packages                                               # 各个平台打包二进制或源码包的相关文件
  12. │   ├── AIX                                                 # 每个OS都有一个子目录
  13. │   │   └── RPM                                          # OS目录下则是当前OS支持打包的格式
  14. │   ├── DOS                                                # 如Linux下的RPM,Win32下的Cygwin exe等
  15. │   ├── EPM
  16. │   ├── Linux
  17. │   │   └── RPM
  18. │   ├── NetWare
  19. │   ├── OS400
  20. │   ├── Solaris
  21. │   ├── Symbian
  22. │   │   ├── bwins
  23. │   │   ├── eabi
  24. │   │   └── group
  25. │   ├── TPF
  26. │   ├── vms
  27. │   └── Win32
  28. │       └── cygwin
  29. ├── src                                                        # curl的源码
  30. │   └── macos
  31. │       └── src
  32. ├── tests                                                     # 测试相关的文件
  33. │   ├── certs                                               # 证书、认证相关的测试
  34. │   │   └── scripts
  35. │   ├── data                                                # 测试相关的数据
  36. │   ├── libtest                                              # 库测试
  37. │   ├── server                                              # 服务器测试
  38. │   └── unit                                                  # 单元测试
  39. └── winbuild                                                 # Windows构建
复制代码
上面简单地描述了curl源码目录的结构和用途,接下来就是对curl的源码进行分析了。
分析curl-7.22.0的源码,主要是从src/, lib/两个目录入手,而且尽量拣重要的文件来进行。


下一篇从src/main.c文件开始,这是curl的main函数入口,按代码的流程对项目进行大致的分析。

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
219 [报告]
发表于 2011-10-17 14:49 |只看该作者
回复 201# duanjigang


    请问。search_makelist中 conn这个结构体是被memset的,后续结构体成员都会被陆续赋值,但在conn_init中为什么直接用conn->ftp->local_if了?
  1. conn->ftp->local_if = conn->local_if;
复制代码
没看到在这之前conn->ftp这个成员怎么赋初值的。conn->ftp难道不是NULL 吗

论坛徽章:
0
220 [报告]
发表于 2011-10-17 15:23 |只看该作者
本帖最后由 duanjigang 于 2011-10-17 15:26 编辑
回复  duanjigang


    请问。search_makelist中 conn这个结构体是被memset的,后续结构体成员都会被陆 ...
seufy88 发表于 2011-10-17 14:49


在conn_t定义中

  1. ftp_t ftp[1];
  2.         http_t http[1];
复制代码
ftp成员不是指针,conn为静态分配或者动态分配的,只要conn不空,conn->ftp就不是空指针。因为它不是一个指针类型成员
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP