C.前面看了一大段是不是有點云里霧里的啊?是有點羅嗦,但是俗話說:“萬事總是開頭難”OK,現在總算可以寫主程序文件了。
  
    下面就是ant.c文件
  
  #include "ant.h"
  #include "signal.h"
                                                                                              //0表示不用,1表示用代理
  int             use_PRoxy;
  //代理服務器的地址
  char            proxy_server[100];
  //端口
  u_short         proxy_port;
  //螞蟻數目
  int             ant_num;
  //下載量
  int             bulk;
  //下載進程
  int             progress;
  char           cfgfile[256];
  char           logfile[256];
  strUCt Ant*    ants[10];
  struct Mission ms;
  //響應異常退出,將url、ant數據結構中的變量值,存放到log文件。
  void  justpause()
  {
  int i;
  FILE* log;
  log=fopen(logfile,"w");
  fprintf(log,"%s ",ms.url);
  for(i=0;iamount!=0)
  fprintf(log, "%d:%d ",ants[i]->position,ants[i]->amount);
  fclose(log);
  exit(1);
  } 
  //總算挨到主程序了,呵呵。。。。。
  int main(int argc,char** argv)
  {
  int            n;
  int            maxfd;
  char           savefile[256];
  FILE*          goods;
  FILE*          log;
  fd_set         rset,aset;
  int            finished;
  int            length;
  char           status[80];
  char           c;
  struct sigaction sa;
  //初始化環境參數
  init_env( );
  //對命令行傳進來的參數做判定
  while((c=getopt(argc,argv,"n:u:s:p:l:h"))!=EOF){
  switch (c){
  //取得螞蟻數目
  case 'n':
  ant_num=atoi(optarg);
  if(ant_num > MAXANTNUM)
  ant_num = MAXANTNUM;
  break;
  //取得目標的url地址。
  case 'u':
  strcpy(ms.url, optarg);
  break;
  //取得代理的地址
  case 's':
  strcpy(proxy_server, optarg);
  use_proxy=1;
  break;
  //取得代理的端口
  case 'p':
  use_proxy=1;
  proxy_port=(u_short)atoi(optarg);
  break;
  //取得日志文件名
  case 'l':
  strcpy(logfile,optarg);
  break;
  case 'h':
  printf("usage: ant -n antnum -u url -s proxyserver -p 
  prxoy_port -l logfile ");
  return 1;
  }
  }
  //從日志文件中讀取url
  if(logfile[0] != 0){
  log = fopen(logfile, "r+");
  strcpy(ms.url,get_url_from_log(log));
  }
  //將值賦代理服務器的相關變量
  if(use_proxy){
  strcpy(ms.host,proxy_server);
  ms.port=proxy_port;
  }else{
  strcpy(ms.host, extract_from_url(ms.url, SITENAME));
  ms.port = atoi(extract_from_url(ms.url, PORTNAME));
  }
  //假如有下載日志,從日志中取相關信息 
  if(logfile[0] != 0){
  printf("The file you havent download,continue.......");
  n=0;
  strcpy(ms.url,get_url_from_log(log));
  while (1) {
  ants[n] = (struct Ant*)malloc(sizeof(struct Ant));
  memset(ants[n], 0, sizeof(struct Ant));
  if(!(assign_mission(log, ants[n])))
  break;
  n++;
  if(n > MAXANTNUM){
  printf("You logfile must be wrong! ");
  exit(1);
  }
  }
  fclose(log);
  free(ants[n]);
  ant_num=n;
  }
  else{
     //取得下載文件的大小,為每只螞蟻分配下載位置。
                         
  bulk=get_size_of_url(&ms); 
  if(bulk==0){
      printf("Cannot get the size of this object! ");
  ant_num=1;
  ants[0] = (struct Ant*)malloc(sizeof(struct Ant));
  ants[0]->position=0;
  ants[0]->amount=1073741823;
  }
  else if(bulk==-1){
    printf("Cannot connect to the site! ");
    exit(1);
  }
  else{
  for(n=0; nposition = (bulk/ant_num)*n;
  if(n!=(ant_num-1))
  ants[n]->amount = bulk/ant_num;
  else
  ants[n]->amount = bulk-(bulk/ant_num)*(ant_num-1);
  } 
  }
  }
  //}
  maxfd=0;
  //重設&rset
  FD_ZERO(&rset);
  //下載,按螞蟻數開線程
  for(n=0; nants[n]->s?maxfd:ants[n]->s;
  }
  }
  if(!maxfd){
  printf("no ant go work! ");
  return 1;
  }
  memset(&sa,0,sizeof(struct sigaction)); 
     //打開存儲文件
  strcpy(savefile, extract_from_url(ms.url, FILENAME));
  if(!(goods=fopen(savefile, "r+"))){
    if(!(goods=fopen(savefile,"w"))){
    printf("Can not open file to save . ");
    exit(1);
    }
  }
  strcpy(logfile, savefile);
  strcat(logfile, ".log");
  //處理進程改變
  sa.sa_handler=justpause; 
  sa.sa_flags=SA_ONESHOT;
  sigaction(SIGINT, &sa, NULL);
  maxfd++;
  finished = 0;
  progress  = 0;
  printf(" ");
  printf("Downloading ....................now! ");
  while(1){
  if(finished==ant_num){
  break;
  }
  aset=rset;
  select(maxfd,&aset,NULL,NULL,NULL);
  for(n=0;ns,&aset)){
    if(!(length=receive(ants[n], goods))){
  unenroll(ants[n], &rset);
  finished++;
  }
  }
  }
  }
  unlink(logfile);
  log=(FILE*)NULL;
     //打開日志文件
  if(ant_num!=1){
    for(n=0;namount){
    if(!log){
  log=fopen(logfile, "w+");
  fputs(ms.url, log);
  fputc(' ',log);
    }
    //保存狀態
    save_status(ants[n], log);
    
    printf("Ant %d have not done!%d ",n+1,ants[n]->amount);
  }
  else
    printf("Ant %d  done! ", n+1);
  free(ants[n]);
    }
  }
  else
    free(ants[0]);
  fclose(goods);
  if(log)
  fclose(log);
  return  1;
  }
  
    D.寫完程序下面就是做makefile.程序比較小,所以MAKEFILE也比較簡單:
  
  CC = gcc
  CFLAGS = 
  source=ant.h ant.c funcs.c
  object=ant.o funcs.o
  ant:$(object)
  $(CC) $(object) -o $@
  %o:%c
  $(CC) -c $< -o $@ $(CFLAGS)
  bak:
  tar czvf ant.tgz Makefile $(source)
  rm -f $(object)
  
    OK.到這總算飛到目的地了。現在你只要在命令行下用“make”命令就可以編譯了。
  
    4。教訓
  
    有一個錯誤,調了很久才發現,就是當fprintf(log,"%s ",ms.url)這樣的語句的指針變量為空時,程序執行過程中就會發生“Segmentation fault (core dumped)”這樣的錯誤。另外,由于程序沒有多加判定,在輸入url時,千萬要帶上“http://”或“FTP://”,哪位網友有愛好可以自己修改。