📄 rfc959.cpp
字号:
/*************************************************** ** 文件名: RFC959.cpp ** 建立日期: 2002年7月24日 ** 作者: 何林强 ** 描述: 这是关于ftp网络连接的部分,ftp协议在 ** RFC959文档中描述. ****************************************************/#include "stdglo.h" /*********************************类CRFC959部分******************/CRFC959::CRFC959(Chftp_Filelist *Filelist,Chftp_Toolbar *hftp_Toolbar){ Remote_Filelist=Filelist; login_dialog=NULL; Connect_data=NULL; downnow=0; hftp_Init_Data(hftp_Toolbar); if(rfc959_Connect()<0) rfc959_disconnect();}CRFC959::~CRFC959(){ rfc959_disconnect(); if(Connect_data) delete Connect_data; if(login_dialog) delete login_dialog;}/***************************************************************** ** 初始化一条连接所用到的全部数据. ****************************************************************/void CRFC959::hftp_Init_Data(Chftp_Toolbar *hftp_Toolbar){ try{ if(!(Connect_data=new Shftp_Connect_data)) throw Chftp_error("内存分配失败,请检查系统后,重启hFTP."); char temp[7]; Connect_data->sockfd_read=NULL; Connect_data->sockfd_write=NULL; Connect_data->datafd=NULL; Connect_data->data_type=HFTP_ASCII; //传输方式初始化文本传输方式. Connect_data->transfer_type=hftp_transfer_passive; //服务器数据连接为被动连接. Connect_data->directory[0]='\0'; Connect_data->last_ftp_response[0]='\0'; strcpy(Connect_data->host_name,gtk_entry_get_text (GTK_ENTRY(GTK_COMBO(hftp_Toolbar->hftp_GetHostname())->entry))); strcpy(temp,gtk_entry_get_text(GTK_ENTRY(hftp_Toolbar->hftp_GetHostport()))); if(0==strcmp(temp,"")) Connect_data->host_port=21; //缺省端口为21. else Connect_data->host_port=atoi(temp); strcpy(Connect_data->user_name,gtk_entry_get_text(GTK_ENTRY(hftp_Toolbar->hftp_GetUser()))); if(0==strcmp(Connect_data->user_name,"")) strcpy(Connect_data->user_name,"anonymous"); //缺省用户名为匿名. strcpy(Connect_data->passwd,gtk_entry_get_text(GTK_ENTRY(hftp_Toolbar->hftp_GetPasswd()))); } catch(Chftp_error& badalloc){ badalloc.messagebox(); }}/********************************* ** 一个定时运行的函数,保活连接用 *********************************/gint CRFC959::idle_function(){ try{ gint reps;gchar command[12]; if (HFTP_BINARY==Connect_data->data_type) strcpy(command, "TYPE I\r\n"); else strcpy(command,"TYPE A\r\n"); reps=rfc959_send_command(command); if(0==strncmp(Connect_data->last_ftp_response,"421",3)){ rfc959_disconnect(); return 0;} if(0!=strncmp(Connect_data->last_ftp_response,"200 Type",8)) rfc959_read_response(); if(reps<0) return 0; return reps; } catch(Chftp_error& badalloc){ badalloc.messagebox(); }}/****************************************** ** 开通一条ftp连接. *****************************************/gint CRFC959::rfc959_Connect(){ gint sockfd,reps,ret,flags; gchar command[50]; if(-2==(sockfd=rfc959_Connect_Server())){ return -2;} //tcp连接打开失败,直接返回. Connect_data->sockfd_read=fdopen(sockfd,"rb"); flags=fcntl(fileno(Connect_data->sockfd_read),F_GETFL,0); if(fcntl(fileno(Connect_data->sockfd_read),F_SETFL,flags|O_NONBLOCK)<0){ fclose (Connect_data->sockfd_read); Connect_data->sockfd_read=NULL; return (-1);} Connect_data->sockfd_write=fdopen(dup(sockfd),"wb"); strcpy(command,"USER "); strcat(command, Connect_data->user_name); strcat(command,"\r\n"); rfc959_read_response(); //服务器端的回复好像滞后了一个,所以先读一个回复,具体原因不明. reps=rfc959_send_command(command); //发送第一条命令,告诉服务器用户名. if(reps<0){ //服务器的回复指令小于零,表示失败. rfc959_disconnect(); return(-2);} if(reps=='3'){ //回复指令第一字节为'3',表示还需要下一条指令. passwdtag=1; //表示开始输入密码了. strcpy(command,"PASS "); strcat(command, Connect_data->passwd); strcat(command,"\r\n"); reps=rfc959_send_command (command); passwdtag=0; if(0!=strncmp(Connect_data->last_ftp_response,"230",3)) rfc959_read_response();} if(reps!='2'){ rfc959_disconnect(); return(-2);} if (HFTP_BINARY == Connect_data->data_type) //发送数据传输方式. strcpy(command, "TYPE I\r\n"); else strcpy(command,"TYPE A\r\n"); if((reps=rfc959_send_command(command))<0){ rfc959_disconnect(); return(-2);} if(0!=strncmp(Connect_data->last_ftp_response,"200 Type",8)) rfc959_read_response(); if((reps=rfc959_send_command("PWD\r\n")) != '2'|| Connect_data->sockfd_read==NULL){ //要求当前的目录名. rfc959_disconnect(); return(-2);} if(0!=strncmp(Connect_data->last_ftp_response,"257",3)) rfc959_read_response(); return 0;}/*********************************************** ** 与服务器的相应ftp端口间打开一条tcp连接. ************************************************/gint CRFC959::rfc959_Connect_Server(){ gint sockfd; struct sockaddr_in serv_addr; struct hostent *host_ip; gchar temp[50]="连向主机:"; strcat(temp,Connect_data->host_name); if(-1==(sockfd=socket(AF_INET,SOCK_STREAM,0))){ Remote_Filelist->hftp_AddStringToList("出现系统错误!"); return(-2); } bzero(&serv_addr,sizeof(serv_addr)); serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(Connect_data->host_port); if(NULL!=(host_ip=gethostbyname(Connect_data->host_name))){ memcpy(&serv_addr.sin_addr,host_ip->h_addr_list[0],host_ip->h_length); } else{ if(inet_aton(Connect_data->host_name, &serv_addr.sin_addr)<0){ Remote_Filelist->hftp_AddStringToList("无效IP地址!"); return(-2); } } Remote_Filelist->hftp_AddStringToList(temp); if(connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in))<0) return(-2); return (sockfd);}gint CRFC959::rfc959_send_command(const char *command){ gchar temp[500]; if (write_to_socket(command)<0){ rfc959_disconnect(); return(-1);} strcpy(temp,command); *(temp+strlen(temp)-2)='\0'; //将命令显示在界面上时去掉多余的换行符. Remote_Filelist->hftp_AddStringToList(temp); printf("%s\n",temp); fflush(stdout); return (rfc959_read_response ());//带回服备器的回馈指令。}gint CRFC959::rfc959_chdir(){ gchar command[200]; gchar ret, *dir; if (0==strcmp(Connect_data->directory,"..")){ ret=rfc959_send_command ("CDUP\r\n");// CDUP的含义为上一层目录。 if('5'==ret) return -2; if(0==strncmp(Connect_data->last_ftp_response,"421 No",6)){ rfc959_disconnect(); return -2;} if(0!=strncmp(Connect_data->last_ftp_response,"250",3)) rfc959_read_response(); } else{ strcpy(command,"CWD "); strcat(command, Connect_data->directory); strcat(command,"\r\n"); ret=rfc959_send_command(command); if(0==strncmp(Connect_data->last_ftp_response,"421 No",6)){ rfc959_disconnect(); return -2;} if('5'==ret) return -2; if(0!=strncmp(Connect_data->last_ftp_response,"250",3)) rfc959_read_response(); } if(ret!= '2') return(-2); if(rfc959_send_command("PWD\r\n")!= '2') return(-2); if(0!=strncmp(Connect_data->last_ftp_response,"257",3)) rfc959_read_response(); return (0);}void CRFC959::rfc959_disconnect(){ if(Connect_data->sockfd_read != NULL){ fclose (Connect_data->sockfd_read); fclose (Connect_data->sockfd_write); Connect_data->sockfd_read = Connect_data->sockfd_write = NULL; if (Connect_data->datafd){ fclose (Connect_data->datafd); Connect_data->datafd = NULL;} }}/************************************************* ** 读回服务器的回馈指令. ************************************************/gint CRFC959::rfc959_read_response(){ try{ gchar response[355], code[4]; gchar tempres[355];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -