⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transfer.cpp

📁 这个是LINUX下的HFTP测试版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    command=g_strconcat("STOR ", filename, "\r\n", NULL);   ret=Rfc959->rfc959_send_command(command);   if('5'==ret){    if(-1==mutitrans) mutex=1;    else mutitrans=1;    fclose(Rfc959->Connect_data->datafd);    Rfc959->Connect_data->datafd=NULL;    return (-2);}  while('4'==ret)    ret=Rfc959->rfc959_send_command(command);  if(0!=strncmp(Rfc959->Connect_data->last_ftp_response,"150",3)     && 0!=strncmp(Rfc959->Connect_data->last_ftp_response,"125",3))    ret=Rfc959->rfc959_read_response();  g_free(command);  if(ret!='1'){    if(-1==mutitrans) mutex=1;    else mutitrans=1;    fclose(Rfc959->Connect_data->datafd);    Rfc959->Connect_data->datafd = NULL;    return (-2);}  sem_post(&bin_sem);  mutex=0;                               //晕倒,一个变量怎么会自己从零变到1的???  pthread_create(&a_thread,NULL,hftp_get_file,(gpointer)this);  strcpy(files[0],filename);              //保存文件名,文件大小,供状态栏显示用。  hftp_convert_size(filesize,&files[1]);  timeout4=gtk_timeout_add(500,updata_progress,(gpointer)this);//0.5秒更新一次状态栏。  return 1;}/************************************************     状态栏更新函数。**********************************************/gint Chftp_transfer::updata_progress(gpointer data){  static glong lastprogress=0;  sem_wait(&(((Chftp_transfer *)data)->bin_sem));  if(0==((Chftp_transfer *)data)->filesize)    sprintf(((Chftp_transfer *)data)->files[2],"100.0%");  else    sprintf(((Chftp_transfer *)data)->files[2],"%2.1f",  //下载进度。	    (1.0*((Chftp_transfer *)data)->progress)/(1.0*((Chftp_transfer *)data)->filesize)*100);  strcat(((Chftp_transfer *)data)->files[2],"%");  ((Chftp_transfer *)data)->hftp_calc_time(          //下载用时跟剩余时间。					   &(((Chftp_transfer *)data)->files[3]),					   &(((Chftp_transfer *)data)->files[4]));  ((Chftp_transfer *)data)->hftp_calc_kbs(           //下载速度。					  &((Chftp_transfer *)data)->files[5]);  if(0==strcmp(((Chftp_transfer *)data)->files[6],"完成")){  //传输完结,更新结束.    strcpy(((Chftp_transfer *)data)->files[6],"等待");    if(0==((Chftp_transfer *)data)->tag)      ((Chftp_transfer *)data)->Rfc959->rfc959_read_response();     sem_post(&(((Chftp_transfer *)data)->bin_sem));    fclose(((Chftp_transfer *)data)->Rfc959->Connect_data->datafd);    ((Chftp_transfer *)data)->Rfc959->Connect_data->datafd=NULL;    fclose(((Chftp_transfer *)data)->myfile);    ((Chftp_transfer *)data)->myfile=NULL;    if(1==((Chftp_transfer *)data)->tag){      if(-2!=(((Chftp_transfer *)data)->Rfc959->rfc959_chdir())){	if(-2!=(((Chftp_transfer *)data)->Rfc959->rfc959_list_files()))	  ((Chftp_transfer *)data)->hftp_read_files(NULL,0);	else{	  if(((Chftp_transfer *)data)->Rfc959->Connect_data->datafd){	    fclose(((Chftp_transfer *)data)->Rfc959->Connect_data->datafd);	    ((Chftp_transfer *)data)->Rfc959->Connect_data->datafd=NULL;}}      }    }    if(-1==((Chftp_transfer *)data)->mutitrans)      ((Chftp_transfer *)data)->mutex=1;    else      ((Chftp_transfer *)data)->mutitrans=1;    return 0;  }  if(0==strncmp(((Chftp_transfer *)data)->files[2],"100.0%",6))    sprintf(((Chftp_transfer *)data)->files[6],"完成");  else if(lastprogress==((Chftp_transfer *)data)->progress)  //下载状态。    sprintf(((Chftp_transfer *)data)->files[6],"等待");  else{    if(1==((Chftp_transfer *)data)->tag)      sprintf(((Chftp_transfer *)data)->files[6],"上传");    else if(0==((Chftp_transfer *)data)->tag)      sprintf(((Chftp_transfer *)data)->files[6],"下载");  }  lastprogress=((Chftp_transfer *)data)->progress;  sem_post(&(((Chftp_transfer *)data)->bin_sem));  if(-1==((Chftp_transfer *)data)->position){          //更新状态栏.    ((Chftp_transfer *)data)->StateBox->State_append(((Chftp_transfer *)data)->files);    ((Chftp_transfer *)data)->position=((Chftp_transfer *)data)->staterows++;  }  else    ((Chftp_transfer *)data)->StateBox->State_updata(((Chftp_transfer *)data)->files,						     ((Chftp_transfer *)data)->position);  return 1;}/******************************************************* **  在数据连接上把文件列表全部读出,并重新组织顺序放入 **  文件列表框. *******************************************************/gint Chftp_transfer::hftp_read_files(Ctransfer_files **tree,gint p_tag){  try{    gchar buf[355];    gchar *pos,*pos2;    gint i;    Ctransfer_files *temp;    if(0==p_tag)      gtk_clist_clear(GTK_CLIST(Remote_Filelist->FileList));     //将列表框原有内容清空.    while(hftp_get_next_request(Rfc959->Connect_data->datafd,buf, sizeof(buf))>0){      pos=pos2=buf;      buf[strlen(buf)-2]='\0';      strncpy(files[5],buf,10);      *(files[5]+10)='\0';      if(*pos=='d') strcpy(files[1],"目录");      else strcpy(files[1],"文件");      pos+=15;pos2+=15;i=0;      while(*pos2!=' '){	*(files[3]+i)=*pos2;	i++;pos2++;}      *(files[3]+i)='\0';      pos+=17;      while(*pos==' ') pos++;      i=0;      while(*pos!=' ') {*(files[2]+i)=*pos;pos++;i++;}      *(files[2]+i)='\0';      hftp_convert_size(strtol(files[2],NULL,10),&files[2]);      pos++;      strncpy(files[4],pos,12);      *(files[4]+12)='\0';      pos+=13;      strcpy(files[0],pos);        if(0==p_tag){	i=gtk_clist_append(GTK_CLIST(Remote_Filelist->FileList),files);	if(0==strcmp(files[1],"文件"))	  gtk_clist_set_pixtext(GTK_CLIST(Remote_Filelist->FileList),i,0,files[0],				1,filestyle[3].pixmap,filestyle[3].mask);	else if((0==strcmp(files[1],"目录")) && (0==strcmp(files[0],".")))	  gtk_clist_set_pixtext(GTK_CLIST(Remote_Filelist->FileList),i,0,files[0],				1,filestyle[2].pixmap,filestyle[2].mask);	else if((0==strcmp(files[1],"目录")) && (0==strcmp(files[0],"..")))	  gtk_clist_set_pixtext(GTK_CLIST(Remote_Filelist->FileList),i,0,files[0],				1,filestyle[1].pixmap,filestyle[1].mask);	else	  gtk_clist_set_pixtext(GTK_CLIST(Remote_Filelist->FileList),i,0,files[0],				1,filestyle[0].pixmap,filestyle[0].mask);      }      else if(1==p_tag){	if(0==strcmp(files[0],"..") || 0==strcmp(files[0],"."))	  continue;	if(!(*tree)){	  if(!(*tree=new Ctransfer_files))	    throw Chftp_error("内存分配失败,请检查系统后,重启hFTP.");	  temp=(*tree);}	else{	  if(!(temp->brother=new Ctransfer_files))	    throw Chftp_error("内存分配失败,请检查系统后,重启hFTP.");	  temp=temp->brother;}	strcpy(temp->filename,files[0]);	if(0==strcmp(files[1],"目录")){	  temp->filesize=0;	  temp->filetype=1;}	else{	  temp->filetype=0;	  temp->filesize=0;}	temp->brother=NULL;      }    }    Rfc959->rfc959_read_response();     if(0!=strncmp(Rfc959->Connect_data->last_ftp_response,"226",3))      Rfc959->rfc959_read_response();      fclose(Rfc959->Connect_data->datafd);    Rfc959->Connect_data->datafd=NULL;    return 1;  }  catch(Chftp_error& badalloc){    badalloc.messagebox();}  return 1;}/*************************************************  文件传输的线程函数************************************************/gpointer Chftp_transfer::hftp_get_file(gpointer arg){  gchar buf[8912];  glong num_read;  ((Chftp_transfer *)arg)->mutex=0;  pthread_detach(pthread_self());  (void)time(&((Chftp_transfer *)arg)->starttime);        //记录开始传输的时间。  while((num_read=((Chftp_transfer *)arg)->               //在一个循环中反复读写数据连接。	 hftp_get_next_file_chunk(buf, sizeof(buf)))>0){    sem_wait(&(((Chftp_transfer *)arg)->bin_sem));    ((Chftp_transfer *)arg)->progress+=num_read;    sem_post(&(((Chftp_transfer *)arg)->bin_sem));    if(((Chftp_transfer *)arg)->hftp_put_next_file_chunk(buf,num_read)<0)      break;  }  ((Chftp_transfer *)arg)->progress=((Chftp_transfer *)arg)->filesize;//传输结束,有可能没有传完.  return(NULL); }/*********************************************** **  从数据连接上读到文件列表信息 **********************************************/gint Chftp_transfer::hftp_get_next_request(FILE *fd,gchar *buf,gint size){  try{    struct timeval tv;    fd_set fset;    g_return_val_if_fail (fd!=NULL, -2);    FD_ZERO(&fset);    FD_SET(fileno(fd),&fset);    tv.tv_sec=5;    tv.tv_usec=0;    if(select(fileno(fd)+1,&fset,NULL,NULL,&tv)<=0){      Remote_Filelist->hftp_AddStringToList("连接超时,请检查网络是否正常!");      Rfc959->rfc959_disconnect();      return (-2);    }    if(!(fgets(buf,size,fd)))      return -2;    return 1;  }catch(...){    return -2;}}/******************************************* **读取文件数据 *******************************************/glong Chftp_transfer::hftp_get_next_file_chunk(gchar *buf, glong size){  try{    struct timeval tv;    FILE* fd;    glong len;    fd_set fset;    g_return_val_if_fail(Rfc959->Connect_data->datafd!=NULL,-2);    g_return_val_if_fail(myfile!=NULL,-2);    if(1==tag) fd=myfile;    else if(0==tag) fd=Rfc959->Connect_data->datafd;    if(size==0) return(0);    FD_ZERO(&fset);    FD_SET(fileno(fd), &fset);    tv.tv_sec=4;    tv.tv_usec=0;    if(select(fileno(fd) + 1,&fset,NULL, NULL, &tv)<=0){      Rfc959->rfc959_disconnect();      return (-1);    }    if((len=read(fileno(fd),buf,size)) < 0)      return (-1);    return len;   }  catch(...){    return -1;}}/****************************************************** **写文件数据 ****************************************************/glong Chftp_transfer::hftp_put_next_file_chunk(gchar *buf, glong size){  try{    struct timeval tv;    FILE *fd;    glong len;    fd_set fset;    char *pos;    g_return_val_if_fail(Rfc959->Connect_data->datafd!=NULL,-2);    g_return_val_if_fail(myfile!=NULL,-2);    if(0==tag) fd=myfile;    else if(1==tag) fd=Rfc959->Connect_data->datafd;    if(0==size) return(0);    pos=buf;    FD_ZERO(&fset);    FD_SET(fileno(fd),&fset);    tv.tv_sec=4;    tv.tv_usec=0;    while(size>0){      if (select (fileno(fd) + 1, NULL, &fset, NULL, &tv)<0){	Rfc959->rfc959_disconnect();	return (-1);      }      if((len=write(fileno(fd), pos, size))<0)	return(-1);      size-=len;      pos+=len;    }    return 1;   }  catch(...){    return -1;  }}/**********************************************  计算传输速度的函数。*********************************************/void Chftp_transfer::hftp_calc_kbs(gchar **speed){  glong difftime;  time_t tv;  (void)time(&tv);  difftime=tv-starttime;  if(difftime==0) sprintf(*speed,"0k/s");  else{    sprintf(*speed,"%.2f",(1.0*progress-1.0*donesize)/1024.0/(1.0*difftime));    strcat(*speed,"k/s");  }}/*********************************************计算传输用时的函数。*******************************************/void Chftp_transfer::hftp_calc_time(gchar **timeuse,gchar **timeleft){  glong difftime;  time_t tv;  (void)time(&tv);  difftime=tv-starttime;  if(difftime==0){    sprintf(*timeuse,"0:0:0");    sprintf(*timeleft,"0:0:0");  }  else{    sprintf(*timeuse,"%ld:%ld:%ld",difftime/3600,(difftime%3600)/60,(difftime%3600)%60);    if(progress==donesize || filesize==donesize) difftime=0;    else      difftime=(glong)(difftime*(1.0-(1.0*progress-1.0*donesize)/(1.0*filesize-1.0*donesize))	/((1.0*progress-1.0*donesize)/(1.0*filesize-1.0*donesize)));    sprintf(*timeleft,"%ld:%ld:%ld",difftime/3600,(difftime%3600)/60,(difftime%3600)%60);  }}/**********************************************文件长度单位换算函数。*********************************************/void Chftp_transfer::hftp_convert_size(glong filesize,gchar **strsize){  gdouble tempsize;  if(filesize>1024*1024*1024){    tempsize=(gdouble)filesize/1024.0/1024.0/1024.0;    sprintf(*strsize,"%.2f%s",tempsize,"G");}  else if(filesize>1024*1024){    tempsize=(gdouble)filesize/1024.0/1024.0;    sprintf(*strsize,"%.2f%s",tempsize,"M");}  else if(filesize>1024){    tempsize=(gdouble)filesize/1024.0;    sprintf(*strsize,"%.2f%s",tempsize,"K");}  else    sprintf(*strsize,"%ld%s",filesize,"B");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -