📄 transfer.cpp
字号:
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 + -