FTP协议详解.docx

上传人:b****4 文档编号:3974025 上传时间:2023-05-06 格式:DOCX 页数:23 大小:141.44KB
下载 相关 举报
FTP协议详解.docx_第1页
第1页 / 共23页
FTP协议详解.docx_第2页
第2页 / 共23页
FTP协议详解.docx_第3页
第3页 / 共23页
FTP协议详解.docx_第4页
第4页 / 共23页
FTP协议详解.docx_第5页
第5页 / 共23页
FTP协议详解.docx_第6页
第6页 / 共23页
FTP协议详解.docx_第7页
第7页 / 共23页
FTP协议详解.docx_第8页
第8页 / 共23页
FTP协议详解.docx_第9页
第9页 / 共23页
FTP协议详解.docx_第10页
第10页 / 共23页
FTP协议详解.docx_第11页
第11页 / 共23页
FTP协议详解.docx_第12页
第12页 / 共23页
FTP协议详解.docx_第13页
第13页 / 共23页
FTP协议详解.docx_第14页
第14页 / 共23页
FTP协议详解.docx_第15页
第15页 / 共23页
FTP协议详解.docx_第16页
第16页 / 共23页
FTP协议详解.docx_第17页
第17页 / 共23页
FTP协议详解.docx_第18页
第18页 / 共23页
FTP协议详解.docx_第19页
第19页 / 共23页
FTP协议详解.docx_第20页
第20页 / 共23页
亲,该文档总共23页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

FTP协议详解.docx

《FTP协议详解.docx》由会员分享,可在线阅读,更多相关《FTP协议详解.docx(23页珍藏版)》请在冰点文库上搜索。

FTP协议详解.docx

FTP协议详解

FTP协议的命令与返回码

FTP命令

命令

描述

ABOR

中断数据连接程序

ACCT

系统特权帐号

ALLO

为服务器上的文件存储器分配字节

APPE

添加文件到服务器同名文件

CDUP

改变服务器上的父目录

CWD

改变服务器上的工作目录

DELE

删除服务器上的指定文件

HELP

返回指定命令信息

LIST

如果是文件名列出文件信息,如果是目录则列出文件列表

MODE

传输模式(S=流模式,B=块模式,C=压缩模式)

MKD

在服务器上建立指定目录

NLST

列出指定目录内容

NOOP

无动作,除了来自服务器上的承认

PASS

系统登录密码

PASV

请求服务器等待数据连接

PORT

IP地址和两字节的端口ID

PWD

显示当前工作目录

QUIT

从FTP服务器上退出登录

REIN

重新初始化登录状态连接

REST

由特定偏移量重启文件传递

RETR

从服务器上找回(复制)文件

RMD

在服务器上删除指定目录

RNFR

对旧路径重命名

RNTO

对新路径重命名

SITE

由服务器提供的站点特殊参数

SMNT

挂载指定文件结构

STAT

在当前程序或目录上返回信息

STOR

储存(复制)文件到服务器上

STOU

储存文件到服务器名称上

STRU

数据结构(F=文件,R=记录,P=页面)

SYST

返回服务器使用的操作系统

TYPE

数据类型(A=ASCII,E=EBCDIC,I=binary)

USER>

系统登录的用户名

FTP响应码

响应代码

解释说明

110

新文件指示器上的重启标记

120

服务器准备就绪的时间(分钟数)

125

打开数据连接,开始传输

150

打开连接

200

成功

202

命令没有执行

211

系统状态回复

212

目录状态回复

213

文件状态回复

214

帮助信息回复

215

系统类型回复

220

服务就绪

221

退出网络

225

打开数据连接

226

结束数据连接

227

进入被动模式(IP地址、ID端口)

230

登录因特网

250

文件行为完成

257

路径名建立

331

要求密码

332

要求帐号

350

文件行为暂停

421

服务关闭

425

无法打开数据连接

426

结束连接

450

文件不可用

451

遇到本地错误

452

磁盘空间不足

500

无效命令

501

错误参数

502

命令没有执行

503

错误指令序列

504

无效命令参数

530

未登录网络

532

存储文件需要帐号

550

文件不可用

551

不知道的页类型

552

超过存储分配

553

文件名不允许

 

 

FTP概述

文件传输协议(FTP)作为网络共享文件的传输协议,在网络应用软件中具有广泛的应用。

FTP的目标是提高文件的共享性和可靠高效地传送数据。

在传输文件时,FTP客户端程序先与服务器建立连接,然后向服务器发送命令。

服务器收到命令后给予响应,并执行命令。

FTP协议与操作系统无关,任何操作系统上的程序只要符合FTP协议,就可以相互传输数据。

本文主要基于LINUX平台,对FTP客户端的实现原理进行详尽的解释并阐述如何使用C语言编写一个简单的FTP客户端。

FTP协议

相比其他协议,如HTTP协议,FTP协议要复杂一些。

与一般的C/S应用不同点在于一般的C/S应用程序一般只会建立一个Socket连接,这个连接同时处理服务器端和客户端的连接命令和数据传输。

而FTP协议中将命令与数据分开传送的方法提高了效率。

FTP使用2个端口,一个数据端口和一个命令端口(也叫做控制端口)。

这两个端口一般是21(命令端口)和20(数据端口)。

控制Socket用来传送命令,数据Socket是用于传送数据。

每一个FTP命令发送之后,FTP服务器都会返回一个字符串,其中包括一个响应代码和一些说明信息。

其中的返回码主要是用于判断命令是否被成功执行了。

命令端口

一般来说,客户端有一个Socket用来连接FTP服务器的相关端口,它负责FTP命令的发送和接收返回的响应信息。

一些操作如“登录”、“改变目录”、“删除文件”,依靠这个连接发送命令就可完成。

数据端口

对于有数据传输的操作,主要是显示目录列表,上传、下载文件,我们需要依靠另一个Socket来完成。

如果使用被动模式,通常服务器端会返回一个端口号。

客户端需要用另开一个Socket来连接这个端口,然后我们可根据操作来发送命令,数据会通过新开的一个端口传输。

如果使用主动模式,通常客户端会发送一个端口号给服务器端,并在这个端口监听。

服务器需要连接到客户端开启的这个数据端口,并进行数据的传输。

下面对FTP的主动模式和被动模式做一个简单的介绍。

主动模式(PORT)

主动模式下,客户端随机打开一个大于1024的端口向服务器的命令端口P,即21端口,发起连接,同时开放N+1端口监听,并向服务器发出“portN+1”命令,由服务器从它自己的数据端口(20)主动连接到客户端指定的数据端口(N+1)。

FTP的客户端只是告诉服务器自己的端口号,让服务器来连接客户端指定的端口。

对于客户端的防火墙来说,这是从外部到内部的连接,可能会被阻塞。

被动模式(PASV)

为了解决服务器发起到客户的连接问题,有了另一种FTP连接方式,即被动方式。

命令连接和数据连接都由客户端发起,这样就解决了从服务器到客户端的数据端口的连接被防火墙过滤的问题。

被动模式下,当开启一个FTP连接时,客户端打开两个任意的本地端口(N>1024和N+1)。

第一个端口连接服务器的21端口,提交PASV命令。

然后,服务器会开启一个任意的端口(P>1024),返回如“227enteringpassivemode(127,0,0,1,4,18)”。

它返回了227开头的信息,在括号中有以逗号隔开的六个数字,前四个指服务器的地址,最后两个,将倒数第二个乘256再加上最后一个数字,这就是FTP服务器开放的用来进行数据传输的端口。

如得到227enteringpassivemode(h1,h2,h3,h4,p1,p2),那么端口号是p1*256+p2,ip地址为h1.h2.h3.h4。

这意味着在服务器上有一个端口被开放。

客户端收到命令取得端口号之后,会通过N+1号端口连接服务器的端口P,然后在两个端口之间进行数据传输。

主要用到的FTP命令

FTP每个命令都有3到4个字母组成,命令后面跟参数,用空格分开。

每个命令都以"\r\n"结束。

要下载或上传一个文件,首先要登入FTP服务器,然后发送命令,最后退出。

这个过程中,主要用到的命令有USER、PASS、SIZE、REST、CWD、RETR、PASV、PORT、QUIT。

USER:

指定用户名。

通常是控制连接后第一个发出的命令。

“USERgaoleyi\r\n”:

用户名为gaoleyi登录。

PASS:

指定用户密码。

该命令紧跟USER命令后。

“PASSgaoleyi\r\n”:

密码为gaoleyi。

SIZE:

从服务器上返回指定文件的大小。

“SIZEfile.txt\r\n”:

如果file.txt文件存在,则返回该文件的大小。

CWD:

改变工作目录。

如:

“CWDdirname\r\n”。

PASV:

让服务器在数据端口监听,进入被动模式。

如:

“PASV\r\n”。

PORT:

告诉FTP服务器客户端监听的端口号,让FTP服务器采用主动模式连接客户端。

如:

“PORTh1,h2,h3,h4,p1,p2”。

RETR:

下载文件。

“RETRfile.txt\r\n”:

下载文件file.txt。

STOR:

上传文件。

“STORfile.txt\r\n”:

上传文件file.txt。

REST:

该命令并不传送文件,而是略过指定点后的数据。

此命令后应该跟其它要求文件传输的FTP命令。

“REST100\r\n”:

重新指定文件传送的偏移量为100字节。

QUIT:

关闭与服务器的连接。

FTP响应码

客户端发送FTP命令后,服务器返回响应码。

响应码用三位数字编码表示:

第一个数字给出了命令状态的一般性指示,比如响应成功、失败或不完整。

第二个数字是响应类型的分类,如2代表跟连接有关的响应,3代表用户认证。

第三个数字提供了更加详细的信息。

第一个数字的含义如下:

1表示服务器正确接收信息,还未处理。

2表示服务器已经正确处理信息。

3表示服务器正确接收信息,正在处理。

4表示信息暂时错误。

5表示信息永久错误。

第二个数字的含义如下:

0表示语法。

1表示系统状态和信息。

2表示连接状态。

3表示与用户认证有关的信息。

4表示未定义。

5表示与文件系统有关的信息。

Socket编程的几个重要步骤

Socket客户端编程主要步骤如下:

1.socket()创建一个Socket

2.connect()与服务器连接

3.write()和read()进行会话

4.close()关闭Socket

Socket服务器端编程主要步骤如下:

1.socket()创建一个Socket

2.bind()

3.listen()监听

4.accept()接收连接的请求

5.write()和read()进行会话

6.close()关闭Socket

实现FTP客户端上传下载功能

下面让我们通过一个例子来对FTP客户端有一个深入的了解。

本文实现的FTP客户端有下列功能:

1.客户端和FTP服务器建立Socket连接。

2.向服务器发送USER、PASS命令登录FTP服务器。

3.使用PASV命令得到服务器监听的端口号,建立数据连接。

4.使用RETR/STOR命令下载/上传文件。

5.在下载完毕后断开数据连接并发送QUIT命令退出。

本例中使用的FTP服务器为filezilla。

在整个交互的过程中,控制连接始终处于连接的状态,数据连接在每传输一个文件时先打开,后关闭。

客户端和FTP服务器建立Socket连接

当客户端与服务器建立连接后,服务器会返回220的响应码和一些欢迎信息。

图1.客户端连接到服务器端

清单1.客户端连接到FTP服务器,接收欢迎信息

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

SOCKETcontrol_sock;

structhostent*hp;

structsockaddr_inserver;

memset(&server,0,sizeof(structsockaddr_in));

 

/*初始化socket*/

control_sock=socket(AF_INET,SOCK_STREAM,0);

hp=gethostbyname(server_name);

memcpy(&server.sin_addr,hp->h_addr,hp->h_length);

server.sin_family=AF_INET;

server.sin_port=htons(port);

 

/*连接到服务器端*/

connect(control_sock,(structsockaddr*)&server,sizeof(server));

/*客户端接收服务器端的一些欢迎信息*/

read(control_sock,read_buf,read_len);

客户端登录FTP服务器

当客户端发送用户名和密码,服务器验证通过后,会返回230的响应码。

然后客户端就可以向服务器端发送命令了。

图2.客户端登录FTP服务器

清单2.客户端发送用户名和密码,登入FTP服务器

1

2

3

4

5

6

7

8

9

10

11

12

13

/*命令”USERusername\r\n”*/

sprintf(send_buf,"USER%s\r\n",username);

/*客户端发送用户名到服务器端*/

write(control_sock,send_buf,strlen(send_buf));

/*客户端接收服务器的响应码和信息,正常为”331Usernameokay,needpassword.”*/

read(control_sock,read_buf,read_len);

 

/*命令”PASSpassword\r\n”*/

sprintf(send_buf,"PASS%s\r\n",password);

/*客户端发送密码到服务器端*/

write(control_sock,send_buf,strlen(send_buf));

/*客户端接收服务器的响应码和信息,正常为”230Userloggedin,proceed.”*/

read(control_sock,read_buf,read_len);

客户端让FTP服务器进入被动模式

当客户端在下载/上传文件前,要先发送命令让服务器进入被动模式。

服务器会打开数据端口并监听。

并返回响应码227和数据连接的端口号。

图3.客户端让服务器进入被动模式

清单3.让服务器进入被动模式,在数据端口监听

1

2

3

4

5

6

7

/*命令”PASV\r\n”*/

sprintf(send_buf,"PASV\r\n");

/*客户端告诉服务器用被动模式*/

write(control_sock,send_buf,strlen(send_buf));

/*客户端接收服务器的响应码和新开的端口号,

*正常为”227Enteringpassivemode()”*/

read(control_sock,read_buf,read_len);

客户端通过被动模式下载文件

当客户端发送命令下载文件。

服务器会返回响应码150,并向数据连接发送文件内容。

图4.客户端从FTP服务器端下载文件

清单4.客户端连接到FTP服务器的数据端口并下载文件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

/*连接服务器新开的数据端口*/

connect(data_sock,(structsockaddr*)&server,sizeof(server));

/*命令”CWDdirname\r\n”*/

sprintf(send_buf,"CWD%s\r\n",dirname);

/*客户端发送命令改变工作目录*/

write(control_sock,send_buf,strlen(send_buf));

/*客户端接收服务器的响应码和信息,正常为”250Commandokay.”*/

read(control_sock,read_buf,read_len);

 

/*命令”SIZEfilename\r\n”*/

sprintf(send_buf,"SIZE%s\r\n",filename);

/*客户端发送命令从服务器端得到下载文件的大小*/

write(control_sock,send_buf,strlen(send_buf));

/*客户端接收服务器的响应码和信息,正常为”213”*/

read(control_sock,read_buf,read_len);

 

/*命令”RETRfilename\r\n”*/

sprintf(send_buf,"RETR%s\r\n",filename);

/*客户端发送命令从服务器端下载文件*/

write(control_sock,send_buf,strlen(send_buf));

/*客户端接收服务器的响应码和信息,正常为”150Openingdataconnection.”*/

read(control_sock,read_buf,read_len);

 

/*客户端创建文件*/

file_handle=open(disk_name,CRFLAGS,RWXALL);

for(;;){

......

/*客户端通过数据连接从服务器接收文件内容*/

read(data_sock,read_buf,read_len);

/*客户端写文件*/

write(file_handle,read_buf,read_len);

......

}

/*客户端关闭文件*/

rc=close(file_handle);

客户端退出服务器

当客户端下载完毕后,发送命令退出服务器,并关闭连接。

服务器会返回响应码200。

图5.客户端从FTP服务器退出

清单5.客户端关闭数据连接,退出FTP服务器并关闭控制连接

1

2

3

4

5

6

7

8

9

10

11

12

13

/*客户端关闭数据连接*/

close(data_sock);

/*客户端接收服务器的响应码和信息,正常为”226Transfercomplete.”*/

read(control_sock,read_buf,read_len);

 

/*命令”QUIT\r\n”*/

sprintf(send_buf,"QUIT\r\n");

/*客户端将断开与服务器端的连接*/

write(control_sock,send_buf,strlen(send_buf));

/*客户端接收服务器的响应码,正常为”200Closesconnection.”*/

read(control_sock,read_buf,read_len);

/*客户端关闭控制连接*/

close(control_sock);

至此,下载文件已经完成。

需要注意的是发送FTP命令的时候,在命令后要紧跟“\r\n”,否则服务器不会返回信息。

回车换行符号“\r\n”是FTP命令的结尾符号,当服务器接收到这个符号时,认为客户端发送的命令已经结束,开始处理。

否则会继续等待。

让我们来看一下FTP服务器这一端的响应情况:

清单6.客户端下载文件时,FTP服务器的响应输出

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

(notloggedin)(127.0.0.1)>Connected,sendingwelcomemessage...

(notloggedin)(127.0.0.1)>220-FileZillaServerversion0.9.36beta

(notloggedin)(127.0.0.1)>220hellogaoleyi

(notloggedin)(127.0.0.1)>USERgaoleyi

(notloggedin)(127.0.0.1)>331Passwordrequiredforgaoleyi

(notloggedin)(127.0.0.1)>PASS*********

gaoleyi(127.0.0.1)>230Loggedon

gaoleyi(127.0.0.1)>PWD

gaoleyi(127.0.0.1)>257"/"iscurrentdirectory.

gaoleyi(127.0.0.1)>SIZEfile.txt

gaoleyi(127.0.0.1)>2134096

gaoleyi(127.0.0.1)>PASV

gaoleyi(127.0.0.1)>227EnteringPassiveMode(127,0,0,1,13,67)

gaoleyi(127.0.0.1)>RETRfile.txt

gaoleyi(127.0.0.1)>150Connectionaccepted

gaoleyi(127.0.0.1)>226TransferOK

gaoleyi(127.0.0.1)>QUIT

gaoleyi(127.0.0.1)>221Goodbye

首先,服务器准备就绪后返回220。

客户端接收到服务器端返回的响应码后,相继发送“USERusername”和“PASSpassword”命令登录。

随后,服务器返回的响应码为230开头,说明客户端已经登入了。

这时,客户端发送PASV命令让服务器进入被动模式。

服务器返回如“227EnteringPassiveMode(127,0,0,1,13,67)”,客户端从中得到端口号,然后连接到服务器的数据端口。

接下来,客户端发送下载命令,服务器会返回响应码150,并从数据端口发送数据。

最后,服务器返回“226transfercomplete”,表明数据传输完成。

需要注意的是,客户端不要一次发送多条命令,例如我们要打开一个目录并且显示这个目录,我们得发送CWDdirname,PASV,LIST。

在发送完CWDdirname之后等待响应代码,然后再发送后面一条。

当PASV返回之后,我们打开另一个Socket连接到相关端口上。

然后发送LIST,返回125之后在开始接收数据,最后返回226表明完成。

在传输多个文件的过程中,需要注意的是每次新的传输都必须重新使用PASV获取新的端口号,接收完数据后应该关闭该数据连接,这样服务器才会返回一个2XX成功的响应。

然后客户端可以继续下一个文件的传输。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2