Chinaunix首页 | 论坛 | 博客
  • 博客访问: 78629
  • 博文数量: 22
  • 博客积分: 145
  • 博客等级: 入伍新兵
  • 技术积分: 181
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-07 16:43
文章分类

全部博文(22)

文章存档

2018年(5)

2017年(2)

2013年(6)

2012年(4)

2011年(5)

我的朋友

分类:

2012-01-16 12:31:25

原文地址:Axel源码学习(3) 作者:define_shore_me

      接着上一篇,我们分析到了setup_thread这个函数,嗯嗯。。。开始要建立连接,也就是说要真正进入状态准备下载了。
      可是建立连接要往下涉及到TCP套接字,究竟是自顶向下还是从下往上慢慢来呢。还是干脆就顺着代码走?这里用第一种方式,先宏观介绍,等以后谈到套接字的时候不辩自明。
      好,我们先来看代码:
  1. void *setup_thread( void *c )
  2. {
  3.     conn_t *conn = c;
  4.     int oldstate;
  5.     
  6.     /* Allow this thread to be killed at any time.            */
  7.     pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldstate );
  8.     pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate );
  9.     
  10.     if( conn_setup( conn ) )
  11.     {
  12.         conn->last_transfer = gettime();
  13.         if( conn_exec( conn ) )
  14.         {
  15.             conn->last_transfer = gettime();
  16.             conn->enabled = 1;
  17.             conn->state = 0;
  18.             return( NULL );
  19.         }
  20.     }
  21.     
  22.     conn_disconnect( conn );
  23.     conn->state = 0;
  24.     return( NULL );
  25. }

       比较关键的函数都是跟conn_t结构体相关的,我们先来分析conn_setup。

 

  1. int conn_setup( conn_t *conn )
  2. {
  3.     if( conn->ftp->fd <= 0 && conn->http->fd <= 0 )
  4.         if( !conn_init( conn ) )
  5.             return( 0 );
  6.     
  7.     if( conn->proto == PROTO_FTP && !conn->proxy )
  8.     {
  9.         if( !ftp_data( conn->ftp ) )    /* Set up data connnection    */
  10.             return( 0 );
  11.         conn->fd = conn->ftp->data_fd;
  12.         
  13.         if( conn->currentbyte )
  14.         {
  15.             ftp_command( conn->ftp, "REST %lld", conn->currentbyte );
  16.             if( ftp_wait( conn->ftp ) / 100 != 3 &&
  17.              conn->ftp->status / 100 != 2 )
  18.                 return( 0 );
  19.         }
  20.     }
  21.     else
  22.     {
  23.         char s[MAX_STRING];
  24.         int i;

  25.         snprintf( s, MAX_STRING, "%s%s", conn->dir, conn->file );
  26.         conn->http->firstbyte = conn->currentbyte;
  27.         conn->http->lastbyte = conn->lastbyte;
  28.         http_get( conn->http, s );
  29.         http_addheader( conn->http, "User-Agent: %s", conn->conf->user_agent );
  30.         for( i = 0; i < conn->conf->add_header_count; i++)
  31.             http_addheader( conn->http, "%s", conn->conf->add_header[i] );
  32.     }
  33.     return( 1 );
  34. }

  建立连接是有两种方式的,一种是FTP服务器的连接,另一个是HTTP。

这里先不展开来讲,大概说一下里面主要函数的作用:

先是FTP:

ftp_data函数是打开一个FTP连接,而且是用PASV命令即被动传输与FTP服务器连接,涉及到TCP连接等。

然后如果以前有下载过的,发个REST命令,接着读服务器状态。看看断点续传是不是正常的。状态为2或者3开头的就代表正常。

接着HTTP:

http_get把GET命令加到conn->request,同时加上其他的设定,譬如权限认证、传输起点和终点。

http_addheader把相应的命令对应的格式加到conn->request上,等下将会发送出去。

conn_setup函数这样就分析得差不多了。接下来,该是conn_exec了,真正开始接收文件了!!看代码!

  1. int conn_exec( conn_t *conn )
  2. {
  3.     if( conn->proto == PROTO_FTP && !conn->proxy )
  4.     {
  5.         if( !ftp_command( conn->ftp, "RETR %s", conn->file ) )
  6.             return( 0 );
  7.         return( ftp_wait( conn->ftp ) / 100 == 1 );
  8.     }
  9.     else
  10.     {
  11.         if( !http_exec( conn->http ) )
  12.             return( 0 );
  13.         return( conn->http->status / 100 == 2 );
  14.     }
  15. }

    代码很短。在FTP中,发送RETR命令获得文件。在HTTP中的http_exec函数就是把刚才的conn->request发送出去。

   好了~~~呼 可以回到文章开头的thread_setup了,大概就这样把连接都setup完,开始下载了。下一篇,我们的目光将又回到axel_start(其实这个函数介绍得差不多了)上,并且看看下载的过程~  高潮来了

阅读(925) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~