首页 > 开发 > 综合 > 正文

linux下的应用开发起步--简化蚂蚁制作(三)

2024-07-21 02:37:29
字体:
来源:转载
供稿:网友

   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://”,哪位网友有爱好可以自己修改。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表