您的位置:首页 > 编程语言 > PHP开发

初始FTP

2016-08-05 00:18 183 查看
FTP简介:

1,文件传输协议FTP(File Transfer Protocol由RFC959描述)

2,FTP设计的目的是为了不同主机之间高效的文件传输,能够屏蔽不同主机不同的文件系统的差异

3,工作在TCP/IP协议族的应用层,传输层使用的是TCP协议,是基于客户/服务器模式工作的

FTP所支持的文件类型(因为是在不同主机的不同文件系统之间进行数据传输,文件共享):

1,ASCII码文件,这是FTP默认的文本格式

2,EBCDIC码文件,它也是一种文本类型文件,用8位代码表示一个字符,该文本文件在传输时,要求两端都使用

  EBCDIC格式

3,图像(Image)文件,也称之为二进制文件,发送的数据为连续的比特流,通常用于传输二进制文件

4,本地文件,(传输的字节数总是由8个bit数构成,但是:逻辑字节数并不总是8个bit数,尽管我们现在  所看到的主机的逻辑地址总是8个.实际上,在早期,有一些主机,它的逻辑字节可能是10位,也可能是36  位,当然也可能是其他的位数,这个时候,逻辑字节数就是由发送方来规定的),所以说:本地文件的字节大小  由本地主机来决定,也就是说:字节的大小是不定的.

  因为ftp是在不同主机不同的文件系统中传输,所以支持这种文件

实际上,大部分的ftp服务器仅仅只是实现了ASCII码文件,图像(Image)文件的传输,而其他的两种文件已经不长用了,所以我们现在编写的ftp也就仅仅只支持ASCII码文件,图像(Image)文件

ASCII码文件:也称为文本文件,如果我们用一个文本编辑器来打开一个文本文件,那么就会将一个个字符显示出来

二进制文件:如果同样的,我们用文本编辑器来打开,很有可能显示的是乱码,,

(上面这些都是我们最直观的感受)

实际上,两者在物理上或者存储结构上没有本质的区别,,,都是由一系列比特位构成的

不同仅仅在逻辑上,或者说系统对它们的解析方式不同

ASCII码文件是由ASCII字符构成的,由7位bit位构成(128个字符),最高位总是0(如果最高位1,那么文     本编辑器很有可能就无法显示,显示的是乱码)

所以说:二进制文件当中的一个字符的最高位很可能是1

这就是两者之间的差别....(还有一个就算:\r\n之间的解析方式不同,我们知道不同的系统的换行符是不一样     的)

    windows:换行符就是\r\n

    Linux:换行符就是\n

    mac:换行符就是\r

    也就是说:在window下打开一个txt文件,我们输入abc,并且按下回车,保存退出,那么当前

         这个文件的大小就应该是5(a,b,c,\r,\n)

也就是说:对于上传的文件(如果是ascii码文件,从window -> Linux,那么会将\r\n转换为

     \n,从Linux -> window,那么会将\n转换为\r\n)

     如果我们强行将上面txt文件中的\r给删除掉的话,那么就变成了二进制上传,传过去不会有影响的

     如果还是上面的txt文件(包括\r\n),并且强制为二进制上传,那么变成什么了呢????

     我们会发现Linux不做任何的解析,这就是它们之间的差别

     简而言之:就是我们的上传的过程中,不建议用ascii码文件上传,因为可能会造成字节的丢失.

FTP文件的数据结构:

1,文件结构:这是FTP默认的方式,文件被认为是一个连续的字节流,文件内部没有表示结构的信息

2,记录结构:由连续的记录构成,该结构只用于文本文件(ASCII码文件,EBCDIC码文件)

3,页结构:在FTP中,文件的一个部分被称为页.当文件是由非连续的多个部分组成的,那么使用页结构

      这种文件称为随机访问文件,每页都带有页号发送,以便接收方能随机的将各个页存储在存储空间中

文件的数据结构会影响文件的传输方式和存储方式

FTP文件的传输方式

1,流方式:这是支持文件传输的默认方式,文件以字节流的方式传输(现如今,主流的ftp服务器)

2,块方式:如果文件是以记录结构的话,那么就可以以块的方式传输,每块前面都带有自己的头部(描述子代码   域(8bit),计数域(16bit)),描述子代码域定义数据块结束标志内容,计数域说明了数据块的

  字节数

3,压缩方式,主要用于对连续出现相同的字节进行压缩,现在已经很少使用啊

FTP的工作原理:

1,FTP是一个C/S架构的软件

  客户端有一个用户界面(可以是比较流行的Leapftp的图像界面,也可以是文本界面(命令行的方式

  来使用))

2,一旦有用户的一个操作就会通过用户协议解析器转换成对应的FTP命令,通过一个控制连接发送给FTP服务器  端,这个控制连接的端口号是21,(首先:客户端跟服务端要建立连接,客户端去连接服务端的21端口,

  建立一个控制连接,控制连接主要是传输命令以及命令的响应,传输命令是由:客户端到服务端;响应命令是   由:服务端到客户端)

3,一旦服务器协议解释器解析到了文件传输的命令之后呢???

  服务端就要跟客户端建立一个新的通道(数据连接通道,这个通道可以由客户端连接过来,也可以由服务端连接  过来,对应两种不同的工作模式),用于传输文件,当然:

  如果是上传的话:客户端读取本地系统当中的文件,传输给服务器端,那么服务器端就将其写入到服务器端的文  件系统

  如果是下载的话:服务端就读取服务端文件系统中的东西,通过数据连接通道,传回给客户端,写入到本地的文  件系统中的



   当我做一个动作,就会产生对应的ftp命令(比如刷新),

   可能会产生这些命令:

   TYPE A(表示以ascii码的方式来传输)

   PORT(实际上,对应FTP的主动模式(ftp有两种模式,一种是主动模式,一种是被动模式),用于建   立数据连接)ftp的核心是传输文件,通道不是采用控制连接,而是采用数据连接,那么这时候,就需要建   立一个数据连接,那么如何建立数据连接呢???也需要双方来进行协商,这里是通过主动模式来进行协商的

   ,一旦服务端得到了这样的数据,就可以建立数据连接,一旦数据连接建立好之后呢,就给客户端一个响应,

   那么客户端就发送一个LIST的长输入列表(也是通过数据连接通道来进行传输的),那么一旦传输完成数   据连接就可以关闭了

   这些就算一个简单的响应,用户的一个动作就会解析出响应的命令(如删除)

对于上面提到的两个连接,控制连接不会关闭,保留时间长,除非我们将控制段关闭,而数据连接通道时间很短,传输完毕就会关闭.

还有就是数据连接的通道:可以是服务端连接过来,也可以是客户端连接过来的.

FTP相对应的命令:

1,访问控制命令:USER(服务器上的用户名)

         PASS(用户口令,匹配上之后会发送一个响应)

         CWD和XCWD(改变工作目录)

         CDUP和XCUP(回到上一层目录,父目录)

2,传输参数命令:PORT(数据端口,主要向服务器发送客户数据连接的端口,格式为:

                                PORT h1,h2,h3,h4,    p1,p2)h表示32位ip,p表示16位端口号

         PASV(此命令要求服务器数据传输进程在随机端口上监听,进入被动接受请求状态)

         TYPE(文件类型:ascii或者二进制)

........(后面还有好多啊)

FTP的应答:

1,不管是FTP的命令或者应答都要在后面加上一个回车和换行(\r\n),都是以此结尾的.

2,如果要产生多行应答,那么第一行就是:3位数字加上"-"在加上应答内容,在最后的时候,我们需要:

  3位数字加上" "(空格)再加上应答内容

  多行应答大部分的情况是对help而言的,而其他的应答是一行(数字+空格)

作用:确保在文件传输过程中,请求和正在执行的动作保持一致,如果没有客户端没有获得应答,那么客户端就会阻   塞,直到接收到应答,从而达到同步的目的

   客户端可以获知服务端当前的状态,根据状态确定发出的请求正确与否...

数字含义:

第一位数字标示了响应是好,坏,未完成

1xy   预备状态

2xy   完成状态

3xy   中间状态

4xy   暂时拒绝状态

5xy   永久拒绝状态

第二位数字标示了发生了什么错误,文件系统,语法错误

0:标示语法错误,给出的命令不存在,多余或没有实现

1:标示信息,对于请求信息的响应

2:标示连接,对于控制连接或者数据连接的响应

3:身份验证和账号

4:未使用

5:文件系统

第三位为第二位更详细的说明:

500:(语法错误,命令不能识别)

501:(参数语法错误)

502:(命令没有实现)

503:(命令顺序错误)

504:(没有实现这个命令的参数)

FTP由两种类型的连接构成:

1,控制连接:主要接收FTP客户端发送过来的命令请求,并且对这些请求进行应答

2,数据连接:主要是双方数据的传输,包括目录列表的传输以及文件的传输

FTP两种工作模式(主要是针对数据连接而言的):

  我们直到控制连接的建立:总是由客户端向服务端发起

  而数据连接通道是不一样的

  1,主动模式(服务器端向客户端发起连接而建立数据连接通道)

  2,被动模式(客户端向服务器端发起连接而建立数据连接通道)

  

  其实,主被动主要是针对服务器端而言的,(服务器端主动的发起连接而建立的通道:主动模式)

  (服务器端被动的接收连接而建立的数据通道:被动模式)

  主动模式:

  


  1,首先要建立一个控制连接通道(如上图:是客户端向服务端的21端口发送一个连接,经过三次握手,建

    立控制连接通道,客户端本地也会选择一个动态的端口号AA,一旦控制连接通道建立好之后,双方就可

    以交换信息了)

  2,客户端可以通过控制连接通道向服务端发起命令请求,服务器端也可以通过控制连接通道对这些命令请求

    进行应答

  3,如果要涉及到数据的传输,那么一定要创建一个数据连接(首先,我们要选择一下工作模式)

    如果是PORT模式:客户端会向服务端发送一个PORT命令(也是通过控制连接通道来完成的,向服

    务端的21端口号传输一个port命令,并且告知客户端的一个端口号BB,因为这个信息,服务端才

    直到要连接客户端的哪一个端口号,然后就向BB端口发起了一个连接的请求,建立了一个数据连接通道

    ,一旦建立完成就可以进行传输了,包括目录列表的传输以及文件的传输,传输完毕。数据连接通道就会关

    闭掉,是临时的)

  4,而且值得我们主要的是:服务端主动连接的时候,服务端选择的是20的端口

    一般情况下:A端连接B端的时候,A端不会选择一个确定的端口(一般都是动态的端口)

  


  1,客户端首先向服务端发起一个PORT命令

    PORT首先需要IP和一个端口,通过控制命令端口发送(PORT  h1,h2,h3,h4,p1,p2)

    后面两个数字:是端口号。。。。。p1表示端口的高八位,p2表示端口的低八位(如

              上:209*256+115 = 53619,到时,服务端要去连接这个端口号)

    PORT模式是主动模式,表示服务端要主动连接客户端

    首先要创建一个数据套接字(TCP),并且绑定一个临时的端口号(就是我们上面求的)(可以用

    bind(0)来表示绑定了一个临时的端口号,但是由于绑定了一个临时的端口号,我们并不了解到底

    是哪一个端口号,我们还必须用getsockname()来获取绑定的到底是哪一个端口号),绑定完了之后

    还需要进行监听,,,

  2,一旦服务端收到这条PORT命令的话,并没有马上建立数据连接,只是将这些信息暂存起来(IP和

    端口暂存起来,以便后续建立数据连接)

    服务端将给客户端一个200的响应。。。

  3,客户端收到这个响应之后,就可以真正的给服务端发送一个数据传输请求,也就是LIST请求。

    服务端收到这个命令之后,要进行检测服务端是不是接收到了PORT或者PASV命令(主被动)。

    如果没有接收过:则响应一个425 Use PORT or PASV first

    如果有接收过:并且是PORT(主动模式),那么服务端就会连接客户端,会创建套接字(并且绑定

    20端口号,调用connect主动连接客户端IP和端口号,从而建立一个数据连接通道)

    一旦通道连接完毕,要告知客户端已经连接就绪了

  4,那么这时候,服务端会向客户端一个应答。150,表示已经准备就绪,可以开始传输了

  5,数据列表的传输

  6,列表传输完毕,服务端发送给客户端一个226的应答。表示传输完毕。。。。。

    服务端主动的关闭数据套接字。。然后客户端得到信息,也关闭了数据套接字。。

    

    我们知道这个时候从编程模型上来看:

    客户端相当于一个服务器,服务端相当于一个客户端(所以说:有时候客户端与服务端的界限不是很明确)

    从用户的角度来看,不管数据连接是如何建立的(不去考虑太多的东西)

被动模式:

     


   1,如上图:首先也是客户端给服务端的21端口发送连接,建立控制连接通道。

   2,选择传输模式,客户端会通过控制连接通道发送PASV命令向服务端。表示被动模式。。。。。。。。

     说明:客户端到时要连接服务端,前提是得知道要连接哪一个端口号(这时候,就需要告知数据连接通

     道的端口号,因而服务端会向客户端一个应答。。。xx:端口号)

   3,一旦客户端接收到应答之后,就可以向那个端口发起连接了,从而建立一个数据连接通道,。

   


   实际上:主被动命令是由客户端来选择的。因为是客户端发起主被动命令的。。。。

   1,客户端向服务端发起一个PASV命令

   2,服务端以一个227的响应。PORT 
h1,h2,h3,h4,p1,p2将IP和端口以这种方式响应给客户端。

     这意味着服务端需要在一个端口号上进行监听。因而需要创建一个数据套接字。绑定一个临时的端口,

     然后在套接字上进行监听。。。还要通过getsockname来获取实际绑定的端口号

     。响应给客户端。以便客户端发起数据连接的请求。

   3,客户端向服务端发送lIST命令。服务端首先判定之前是不是收到PORT或者PASV命令

     如果没有的话,依然响应一个:425 Use PORT or PASV first

     如果有的话,并且是PASV,则服务端调用accept接收客户端的请求。从而建立数据连接

   4,然后,服务端向客户端响应一个150,表示准备就绪,可以传输了 

   5,开始传输

   6,服务端发送226应答给客户端,表示传输结束。。。。断开数据连接通道。。。

   同样一个简单的问题:

   FTP服务器:为什么要有两种工作模式呢???为什么要存在主动模式,被动模式呢???

   这实际上跟NAT或者防火墙对主动模式或者被动模式有关系的。。。。

   什么是NAT???

   1,全称是:Network Address Translation网络地址转换。通过NAT可以将内网私有IP地址转换为公网

     IP地址。一定程度上解决了公网地址不足的问题。。。

     我们知道:局域网上的主机很多都没有公网的IP。但是我们局域网上的主机要跟外界进行通信,这个

     时候就需要得到一个公网的IP地址。这个时候,就涉及到了NAT

     


     私有的IP地址不能直接跟公网的IP地址进行通信。那么这个时候就要进行地址转换。

     通过一个NAT服务器(双网卡,有两个接口,一个局域网的接口,一个连至公网)

     如上:客户端(192.168.1.100)要跟服务端(50.118.99.200)进行通信,那么会首先经过一个

     NAT进行地址映射。将(192.168.1.100)地址转换为:(120.35.3.193)从而连接外网的一个服务器。

     同时还有一个端口的映射。。。

     也就是说:局域网中的主机基本上都没有配备公网IP,利用NAT公用一个公网,进行外界通信。。。

2,NAT跟ftp的主被动关系!!!

  1,ftp客户端处于NAT或防火墙之后的主动模式

  


               1,主动模式是先创建控制连接通道(由于局域网上的主机无法访问Internet网上的服务器,因而

      需要经过NAT服务器。。)NAT服务器有一个特征:如果是从内部向外建立连接,那么是可以的。

      客户端从内部向外界发起连接,这时候NAT服务器内部会维护一个表目(IP的映射)

      从而建立控制连接通道。

      实际上:服务端收到的IP和端口号,是由NAT转换后的IP和端口号。。。

      (192.168.1.100,5390)地址转换为:(120.35.3.193,5390)

      上面的端口号为5390,我们假设它们的端口号都没有改变,同等映射。

      外界主动发起的连接,连接的也是NAT的IP和端口号

      实际上:NAT并没有在BB端口号上进行监听,是客户端在BB端口号上进行监听。。。因此:服务

      器和NAT没有办法成功建立连接(也就是说:服务器并没有将局域网上的客户端当做客户端,实际

      上是将这个NAT服务器当做一个客户端的,但是它本不是客户端,所以连接建立失败)

      如何解决这个问题呢??

      1,在NAT服务器上配置映射,允许服务端连接过来(我们要配置映射条目,手工的)

        如果是手工的配置的话,那么就需要知道服务端到底是哪一个端口连接过来的,这也是服务端这边

        建立一个连接绑定20端口的原因。而不是让其动态选择。

        如果是动态选择的话,那就说明NAT要维护的映射信息就会很多。 

        当然:也有一些NAT能自动的维护条目,但是需要确定的端口20,21的协调

  

  2,ftp客户端处于NAT或防火墙之后的被动模式

    


    1,客户端向服务端21端口发起连接,可以成功

    2,通过控制连接通道发起了一个PASV请求

    3,服务端会创建一个数据套接字绑定监听端口号xx,并且将这个信息告知给客户端,以便客户端向

      这个端口xx发起连接

    4,客户端发起连接跟服务端xx建立,总能够成功

ftp服务器处于NAT或防火墙之后的被动模式

    


    也就是说:这个服务器是在局域网中的,并没有跟外界连通。服务器处于防火墙之后。

    客户端要连接服务器,实际上要通过NAT服务器,

    首先,客户端(处于INTER之上)与NAT建立一个连接(三次握手,建立控制连接通道)NAT

    也需要一个映射,将21端口号映射至服务器端才可以,这样就实现了客户端跟服务端的建立。

    实际上:客户端总是跟NAT进行交互的,因为有公网的IP地址。

    同样的,最终的通道客户端发起xx(NAT没有办法维护)失败。。。(从外界发起无法成功)

      


      这回就是可以的了,,,,

    

        
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: