写在前面的话:也没有做过源码分析,确实拿到了源码之后以前就只是看看源码里面坐着写的那些很给力的工具类之类的,比如以前看zermoq,czmq, lighthttpd这些大神级源码,我大都还是停留在看看他们写的工具类,比如:hash, map, list, arraylist等等这些工具集拿来然后用在我自己的工程里面,这么着确实给我的工作带来了很多的方便,但是也是凸显出我对很多的源码其实并未深入其中的。
这次来到上海了,工作不是很忙,所以还是想专心下来,看看所有的源码,提高自己的能力为主要目标,源码分析每个人有每个人的看源码的方式,其实我看源码的方式就比着网上的大神来说还是比较low的,希望看我的文档的不要嫌弃才对哈,呵呵,有些的不对的地方,或者不太符合各位的看源码习惯的同仁,希望给我提提意见,我后面也按照各位看源码的方式阅读试试,是不是更有效率一点。
我看源码其实就分3步:
1:看一下源码的大致的结构,这一步,我其实就看看,OK源码里面有工具类,有业务类,源码主次分的很清楚,就行了
2:把所有更业务相关的工具类全部通读一遍,这一步,我就只单纯的看源码里面的工具类,比如log, list等等,这些东西反正跟这个工程业务来说关系不是很大,拿出来以后我们自己可以在我们自己的工程里面也能使用。
3:有了上面工具类看完之后,开始看工程业务类的代码,OK这就是主线了,看完了基本上整个工程就相当于有了灵魂,把第二步的工具也都串联起来了。
这次源码分析我就先拿wget来下手了,为什么呢?随手从自己的Source Insight工程里面搞了一个出来了,也没什么目的,哈哈!
好了,废话不说了,那首先得说说wget的作用
1、下载整个http或者ftp站点。
2、断点续传。
3、批量下载。
4、选择性的下载。
5、密码和认证。
6、利用代理服务器进行下载。
目前分析的这一版的wget是1.9是支持ssl的,不用再使用curl去下载了。
下面正式开始源码分析过程;
先组织一下文件结构吧:
打开wget1.9/src目录,
工具类的.C文件如下
url.c+url.h : url工具类
hash.c+hash.h : hash表类
gnu-md5.c + gnu-md5.h : md5处理类
无依赖文件
Options.h, sysdep.h, log.c , snprintf.c , alloca.c
ansi2knr.c, cmpt.c
剩下的文件就是wget整个工程都会用到基础类库+业务处理类,这些文件之间大都会相互依赖,到了那些地方我再一一说明也不迟,先从最简单,无任何依赖的文件开始看,化繁为简。
Options.h -- 就是wget参数选项的一个结构体
全文就一个结构体,很清晰
struct options
{
int verbose;/* 冗长模式(这是缺省设置)? */
int quiet;/* 安静模式(没有输出) */ 是否安静
int ntry;/* 设定最大尝试链接次数(0 表示无限制). */
int retry_connrefused;/* 连接拒绝重试. */
int background;/* 是不是工作在后台*/
int kill_longer;/* 超过指定的content-length” 是够拒收消息*/
int ignore_length; /* 是否忽视“content-length”*/
int recursive;/* 是否递归*/
int spanhost;/*当递归时转到外部主机*/
int relative_only;/* 仅仅跟踪相对链接*/
int no_parent;/* 不要追溯到父目录*/
int reclevel;/* 最大递归深度 (inf 或 0 代表无穷).*/
int dirstruct;/* 强制创建目录*/
int no_dirstruct;/* 不创建目录*/
int cut_dirs;/* 忽略cut_dirs层远程目录*/
int add_hostdir;/* 是否增加主机目录*/
int noclobber;/* 不要覆盖存在的文件或使用.#前缀*/
char *dir_prefix;/* 将文件保存到目录 PREFIX/...*/
char *lfilename;/* 日志文件 */
char *input_filename;/* input文件名 */
int force_html;/* 把输入文件当作HTML格式文件对待? */
int spider;/* 不下载任何东西 */
char **accepts;/* 分号分隔的被接受扩展名的列表 */
char **rejects;/* 分号分隔的不被接受的扩展名的列表 */
char **excludes;/* 不被包含目录的列表*/
char **includes;/* 允许目录的列表 */
char **domains;/* 分号分隔的被接受域的列表 */
char **exclude_domains; /*分号分隔的不被接受的域的列表*/
int dns_cache;/* 是不是缓存dns */
char **follow_tags; /* 分号分隔的被跟踪的HTML标签的列表. */
char **ignore_tags; /* 分号分隔的被忽略的HTML标签的列表*/
int follow_ftp;/*