日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实验13 简单FTP 程序设计

發布時間:2025/1/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实验13 简单FTP 程序设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

實驗13簡單FTP 程序設計


實驗目的:設計一個簡單的FTP 客戶端,支持用戶登錄,瀏覽目錄列表,上傳

文件和下載文件的功能。

實驗內容:

程序的偽代碼如下:

(假定FTP 用戶名為user_name,密碼為pass_word

主函數:

1 連接FTP 服務器的21 端口

2 等待FTP 服務器回應,若應答碼不為220,則報錯

3 FTP 服務器21 端口發送"USER user_name\r\n"字符串,等待FTP ?回應,若

應答碼不為331,則報錯。

4 FTP 服務器21 端口發送"PASS pass_word\r\n"字符串,等待FTP 回應,若應

答碼不為230,則報錯:用戶與密碼不匹配。

while(1)

{

5 等待用戶輸入命令cmd;

6 cmd quit,則關閉套接字,退出程序

7 cmd ls dirlist_file(sock)

8 cmd put abc.xyz,則調用up_file(sock,abc.xyz)

9 cmd get abc.xyz,則調用down_file(sock,abc.xyz)

}

/*

函數名list_file

函數功能:顯示ftp 服務器上文件列表

@sock : ftp ?服務器控制端口對應的套接字

*/

函數list_file(int ?sock)

{

//sock ?對應了ftp 21 端口

1 sock 發送"TYPE I\r\n",等待應答碼200

2 sock 發送"PASV\r\n",等待應答碼227

3 sock 發送過來的字符串中尋找形如(xx,xx,xx,xx,xx, xx)的子串,從該字符串

中提取IP 地址和端口號。建立新套接字sock2,連接該IP 地址和端口號。

4 sock 發送"LIST\r\n"

5 sock2 中讀取字符串,直到對方關閉


6 sock 中讀取回應碼,若不為226,則報錯

}

/*

函數名up_file

函數功能:上傳本地文件到ftp 服務器

@sock : ftp ?服務器控制端口對應的套接字

@args: 要上傳的文件名

*/

函數up_file(int ?sock,char args)

{

1 在本地打開args 對應的文件,其文件指針為fp1

2 sock 發送"TYPE I\r\n",等待應答碼200

3 sock 發送"PASV\r\n",等待應答碼227

4 sock 發送過來的字符串中尋找形如(xx,xx,xx,xx,xx,xx)的子串,從該字符串

中提取IP 地址和端口號。建立新套接字sock2,連接該IP 地址和端口號。

5 sock 發送"STOR args 對應文件名\r\n"

6 fp1 指向的文件逐字節的讀出,并且寫入sock2 中,寫完后關閉sock2

7 等待sock 的回應,回應碼為226

}

/*

函數名up_file

函數功能:下載ftp 服務器文件到本地

@sock : ftp ?服務器控制端口對應的套接字

@args: 要下載的文件名

*/

函數down_file(int ?sock,char args)

{

1 在本地打開args 對應的文件,其文件指針為fp1

2 sock 發送"TYPE I\r\n",等待應答碼200

3 sock 發送"PASV\r\n",等待應答碼227

4 sock 發送過來的字符串中尋找形如(xx,xx,xx,xx,xx,xx)的子串,從該字符串

中提取IP 地址和端口號。建立新套接字sock2,連接該IP 地址和端口號。

5 sock 發送"SIZE args 對應文件名\r\n" ,若回應碼不為213則沒有這個文件

或通信過程出錯。

6 sock 發送"RETR args 對應文件名\r\n"

7 sock2 中內容逐字節的讀出,并且寫入fp1 的文件,寫完后關閉sock2 fp1

8 等待sock 的回應,回應碼應該為226,否則報錯

}


附錄:

代碼實現:

#include ?<sys/socket.h>

#include ?<netinet/in.h>

#include ?<arpa/inet.h>

#include ?<fcntl.h>

#include ?<unistd.h>

#include ?<stdio.h>

#include ?<errno.h>

#include ?<netdb.h>

#include ?<pwd.h>

#include ?<termios.h>

#define BUFSIZE ?1024

char buf[BUFSIZE];

char sendbuf[BUFSIZE];

void err_sys(char ?*s)

{

printf("%s",s);

exit(-1);

};

void err_sysa(int ?a,char *s)

{

printf("status=%d %s",a,s);

exit(-1);

};

void terminal_echo_off(int ?fd)

{

struct termios oldterm;

tcgetattr(fd,&oldterm);

oldterm.c_lflag &=~ECHO;

tcsetattr(fd,TCSAFLUSH,&oldterm);

};

int active_listen()

{

int sockfd;

sockfd=socket(AF_INET,SOCK_STREAM,0);

if(sockfd==-1)

fprintf(stderr,"socket error!");

struct sockaddr_in localaddr;


localaddr.sin_family=AF_INET;

inet_aton("0.0.0.0",&localaddr.sin_addr);

localaddr.sin_port=0;

int bret=bind(sockfd,(struct ?sockaddr*)&localaddr,sizeof localaddr);

if(bret==-1)printf("bind ?error!\r\n");

return sockfd;

};

unsigned ?int get_port(int fd)

{

struct sockaddr_in sa;

unsigned int port;

int sin_size=sizeof(struct sockaddr_in);

getsockname(fd,(struct sockaddr*)&sa,&sin_size);

port=ntohs(sa.sin_port);

return port;

};

void hexprint(char ?*x)

{

int i=0;

while(x[i]!=0)

{

printf("%x ?",x[i]);

i++;

}

printf("\r\n");

};

void terminal_echo_on(int ?fd)

{

struct termios oldterm;

tcgetattr(fd,&oldterm);

oldterm.c_lflag |= ECHO;

tcsetattr(fd,TCSAFLUSH,&oldterm);

};

void getaddrin(struct ?sockaddr_in *pdest)

{

char *start=strchr(buf,'(');

start++;

char *end=strchr(buf,')');


*end=0;

char *pi;

for(pi=start;pi<end;pi++)

if(*pi==',')*pi=' ';

char ci1[4],ci2[4],ci3[4],ci4[4],ci5[4],ci6[4];

int c1,c2,c3,c4,c5,c6;

sscanf(start,"%s%s%s%s%s%s",ci1,ci2,ci3,ci4,ci5,ci6);

c1=atoi(ci1);

c2=atoi(ci2);

c3=atoi(ci3);

c4=atoi(ci4);

c5=atoi(ci5);

c6=atoi(ci6);

int ip=c1<<24|c2<<16|c3<<8|c4;

short port=c5<<8|c6;

struct sockaddr_in ?dest;

pdest->sin_family=AF_INET;

pdest->sin_port=htons(port);

pdest->sin_addr.s_addr=htonl(ip);

};

void sendftp(const ?char* cmd,int fd)

{

sprintf(sendbuf,cmd);

write(fd,sendbuf,strlen(sendbuf));

};

void down_file(int ?sock,const char* args)

{

//下載文件

sendftp("TYPE I\r\n",sock);

int ftp_status=recvftp(sock);

if(ftp_status!=200){printf("ftp_status=%d\r\n",ftp_status);err_sys("類型錯誤

\r\n");};

sendftp("PASV\r\n",sock);

ftp_status=recvftp(sock);

if(ftp_status!=227)err_sys("進入被動模式錯誤\r\n");

struct sockaddr_in dest;

getaddrin(&dest);//通過被動模式,設置要連接的地址和端口

int fsock=socket(AF_INET,SOCK_STREAM,0);


if(fsock<=0)err_sys("socket2 創建錯誤\r\n");

if(connect(fsock,(struct sockaddr*)&dest,sizeof(dest))==-1)err_sys("無法連接

FTP 控制端口\r\n");

char tempbuf[512];

sprintf(tempbuf,"SIZE /%s\r\n",args);

sendftp(tempbuf,sock);

ftp_status=recvftp(sock);

if(ftp_status==213)

{

sprintf(tempbuf,"RETR ?/%s\r\n",args);

sendftp(tempbuf,sock);

ftp_status=recvftp(sock);

if(ftp_status!=150)err_sys("RETR ?錯誤!\r\n");

FILE * fp=fopen(args,"w+");

printf("%s\r\n",args);

if(fp==NULL)err_sys("nihaod");

while(1)

{

int n=read(fsock,buf,BUFSIZE);

if(n<=0)break;

fwrite(buf,sizeof(char),n,fp);

}

fflush(fp);

fclose(fp);

printf("文件下載完畢\r\n");

ftp_status=recvftp(sock);

if(ftp_status!=226)err_sysa(ftp_status,"文件傳輸錯誤226!\r\n");

}

else if(ftp_status==550)

{

printf("沒有這個文件%s\r\n",args);

}

else err_sys("錯誤ftp ?代碼");

close(fsock);

};

void up_file(int ?sock,const char* args)

{

FILE * fp=fopen(args,"r");

printf("%s\r\n",args);

if(fp==NULL){printf("無此文件\r\n");return;};


int flen;

fseek(fp,0,SEEK_END);

flen=ftell(fp);

fseek(fp,0,SEEK_SET);

//上傳文件

sendftp("TYPE I\r\n",sock);

int ftp_status=recvftp(sock);

if(ftp_status!=200){printf("ftp_status=%d\r\n",ftp_status);err_sys("類型錯誤

\r\n");};

sendftp("PASV\r\n",sock);

ftp_status=recvftp(sock);

if(ftp_status!=227)err_sys("進入被動模式錯誤\r\n");

struct sockaddr_in dest;

getaddrin(&dest);//通過被動模式,設置要連接的地址和端口

int fsock=socket(AF_INET,SOCK_STREAM,0);

if(fsock<=0)err_sys("socket2 創建錯誤\r\n");

if(connect(fsock,(struct sockaddr*)&dest,sizeof(dest))==-1)err_sys("無法連接

FTP 控制端口\r\n");

char tempbuf[512];

sprintf(tempbuf,"STOR ?/%s\r\n",args);

sendftp(tempbuf,sock);

ftp_status=recvftp(sock);

if(ftp_status!=150)err_sys("STOR ?錯誤!\r\n");

FILE* sockfp=fdopen(fsock,"w");

if(sockfp==NULL)err_sys("sockfp ?錯誤\r\n");

int i;

for(i=0;i<flen;i++)

fputc(fgetc(fp),sockfp);

fflush(sockfp);

fclose(sockfp);

fclose(fp);

ftp_status=recvftp(sock);

if(ftp_status!=226)err_sysa(ftp_status,"文件傳輸錯誤226!\r\n");

printf("文件上傳完畢\r\n");

close(fsock);

};

void list_file(int ?sock)

{


sendftp("TYPE I\r\n",sock);

int ftp_status=recvftp(sock);

if(ftp_status!=200){printf("ftp_status=%d\r\n",ftp_status);err_sys("類型錯誤

\r\n");};

sendftp("PASV\r\n",sock);

ftp_status=recvftp(sock);

if(ftp_status!=227)err_sys("進入被動模式錯誤\r\n");

struct sockaddr_in dest;

getaddrin(&dest);

int fsock=socket(AF_INET,SOCK_STREAM,0);

if(fsock<=0)err_sys("socket2 cuo wu\r\n");

if(connect(fsock,(struct sockaddr*)&dest,sizeof(dest))==-1)err_sys("wu ?fa lianjian

dui fang\r\n");

sendftp("LIST\r\n",sock);

ftp_status=recvftp(sock);

if(ftp_status!=150)err_sys("打開文件錯誤!\r\n");

while(1)

{

int n=read(fsock,buf,BUFSIZE);

if(n<=0)break;

buf[n]=0;

printf("%s",buf);

}

ftp_status=recvftp(sock);

if(ftp_status!=226)err_sysa(ftp_status,"226 ?錯誤(250)!\r\n");

close(fsock);

}

int checkcode(const ?int s,const int t)

{

if(s==t)

{

return 1;

}

else

{

printf("wrong code!\r\n");

}

return 0;

}

int recvftp(int ?fd)


{

//返回ftp ?代碼,并且將所有字符串寫在buf

int n=read(fd,buf,BUFSIZE);

char stabuf[4];

buf[n]=0;

sscanf(buf,"%3s",stabuf);

int ftpcode=atoi(stabuf);

if(ftpcode<=0)err_sys("返回碼錯誤\r\n");

return ftpcode;

}

void promt(const ?char* s,char *cmd)

{

printf("%s",s);

fgets(cmd,32,stdin);

}

int main(int ?argc,char* argv[])

{

char cmd[32];

int ftp_status=0;//ftp 服務器返回碼

struct hostent *host;

if((host=gethostbyname(argv[1]))==NULL)

err_sys("Get hostanme error!\r\n");

int port=atoi(argv[2]);

if(argc==3&&port<0)

{

fprintf(stderr,"Usage:%s hostname ?portnumber\r\n",argv[0]);

exit(-1);

}

/*生成套接字*/

int sock=socket(AF_INET,SOCK_STREAM,0);

if(sock<=0)err_sys("socket ?error!\r\n");

/*FTP 服務器套接字地址*/

struct sockaddr_in ?server_addr;

server_addr.sin_family=AF_INET;

server_addr.sin_port=htons(port);

server_addr.sin_addr=*((struct ?in_addr*)host->h_addr);

/*連接服務器*/

int conret=connect(sock,(struct ?sockaddr*)&server_addr,sizeof server_addr);

if(conret==-1)

{


fprintf(stderr,"connect error:%s\r\n",strerror(errno));

exit(-1);

}

/*獲得FTP ?返回碼*/

ftp_status=recvftp(sock);

if(ftp_status!=220)err_sys("登錄錯誤無法連接!220 \r\n");

printf("請輸入[%s]用戶名:(直接回車為默認的anonymous)

",inet_ntoa(server_addr.sin_addr));

fgets(cmd,sizeof(cmd),stdin);

//scanf(cmd,"%s");

cmd[strlen(cmd)-1]=0;//最后一個字符是0a,所以要去掉

if(strlen(cmd)!=0)

{

sprintf(sendbuf,"USER %s\r\n",cmd);

sendftp(sendbuf,sock);

ftp_status=recvftp(sock);

if(ftp_status!=331)err_sys("登錄錯誤無法連接! 331\r\n");

terminal_echo_off(STDIN_FILENO);

printf("請輸入密碼: ");

fgets(cmd,sizeof(cmd),stdin);

terminal_echo_on(STDIN_FILENO);

cmd[strlen(cmd)-1]=0;//最后一個字符是0a,所以要去掉

sprintf(sendbuf,"PASS ?%s\r\n",cmd);

sendftp(sendbuf,sock);

ftp_status=recvftp(sock);

if(ftp_status!=230)err_sys("密碼錯誤230\r\n");

}

else

{

sendftp("USER anonymous\r\n",sock);

ftp_status=recvftp(sock);

sendftp("PASS IEUSER@\r\n",sock);

ftp_status=recvftp(sock);

if(ftp_status!=230)err_sys("不支持匿名登錄\r\n");

}

printf("建立和ftp ?服務器的連接\r\n");

/*進入被動模式*/

char totalcmd[512];


char args[256];

while(1)

{

while(1)

{

promt("請輸入命令:",totalcmd);

sscanf(totalcmd,"%s%s",cmd,args);

if(cmd==NULL){printf("輸入命令錯誤,重新輸入命令");continue;};

if(strcasecmp(cmd,"quit")==0)

{

printf("退出程序!\r\n");

close(sock);

exit(0);

}

break;

}

if(strcasecmp(cmd,"ls")==0||strcasecmp(cmd,"dir")==0)

list_file(sock);

if(strcasecmp(cmd,"GET")==0)down_file(sock,args);

if(strcasecmp(cmd,"PUT")==0)up_file(sock,args);

}

}




轉載于:https://blog.51cto.com/wolfword/1240349

總結

以上是生活随笔為你收集整理的实验13 简单FTP 程序设计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。