FTP简介:
FTP(File Transfer Protocol):是应用层的一个文件传输协议 。主要作用是在服务器和客户端之间实现文件的传输和共享。FTP协议运行在TCP连接上,保证了文件传输的可靠性。在传输时,传输双方的操作系统、磁盘文件系统类型可以不同。
FTP协议:允许TCP/IP网络上的两台计算机之间进行文件传输。而FTP服务是基于FTP协议的文件传输服务。工作时,一台计算机上运行FTP客户端应用程序,另一台计算机上需要运行FTP服务器端程序。只有拥有了FTP服务,客户端才能进行文件传输。
Ⅰ.与HTTP的区别:
HTTP和FTP都是文件传输协议,都是运行在TCP上面,但是他们也有一些重要的区别。
FTP使用了两个并行的TCP来传输文件:一个是控制连接(port:21),一个是数据连接(port:20)。控制连接用于在两个主机之间传输控制信息,如口令,用户标识,存放、获取文件等命令。数据连接用于实际发送一个文件,发送完文件之后数据连接会关闭。因为FTP协议使用一个独立的控制连接,所以,也称FTP的控制信息是带外(out-of-band)传送的。
HTTP协议是在传输文件的同一个TCP连接中发送请求和相应首部行的。因此,HTTP也可以说是带内(in-band)发送控制信息。
Ⅱ.FTP协议的2种传输方式:
FTP支持两种方式的传输:文本(ASCII)方式和二进制(Binary)方式。
通常文本文件的传输采用ASCII方式;而图象、声音文件、加密和压缩文件等非文本文件采用二进制方式传输;
Ⅲ.FTP的2种传输模式:
FTP有两种传输模式——主动(FTP Port)模式和被动(FTP Passive)模式。由于主动模式存在着安全问题,最近几年,大部分的TFP客户端开始默认使用被动模式。
被动方式(Passive):
由于主动方式中,服务端需要主动连客户端,对于客户端的防火墙来说,属于外部连接内部,会出现被阻塞的情况。被动方式解决了这个问题。被动连接的核心是——控制连接请求和数据连接请求都是由客户端发起。
被动方式的步骤如下:
1.客户端任意打开约1024的两个本地端口(P1和P1+1)
2.P1端口发送请求连接服务器的21端口(控制连接端口)同时提交PASV命令。
3.服务器收到请求后,会开启任意一个大约1024的端口P2,然后返回如下格式内容:
227 entering passive mode(h1,h2,h3,h4,p1,p2)
4.客户端收到服务端返回的内容后,计算出服务端开放的数据连接端口
5.客户端通过P1+1端口向服务端的发送连接请求。进行数据传输
关于服务端返回的报文格式(h1,h2,h3,h4,p1,p2)具体含义如下:
h1,h2,h3,h4代表服务器的ip地址;
p1,p2代表服务器监听的数据连接端口地址。计算方法为P1*256+P2
FTP的限制:当客户端用户数量不断增多,FTP服务器所要维持的会话总数,也会迅速增长。这会大大限制FTP服务器的性能。
应答:
FTP客户端每个发出的命令都会对应一个FTP服务器发出的应答。应答是一个3位的数字,后跟一个可选信息。他与HTTP响应报文的状态码和状态信息的结构相同,比较常见的几个应答可以参考如下:
以上内容参考文章:https://zhuanlan.zhihu.com/p/337513218 (侵删)
FTP服务器应用:
环境配置:Win10、IDEA2020、easyftp-server-1.7.0.10
1.文件列表显示
public class ftp {
public static void main(String[] args) {
//创建基于FTP协议访问的文件服务器的客户端对象
FTPClient ftpClient = new FTPClient();
try {
//连接服务器验证用户名密码
ftpClient.connect("127.0.0.1",21);//IP地址,端口号
ftpClient.login("admin","123456");//验证用户名密码
SimpleDateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日");//设置时间格式
//获取当前目录中所有文件
FTPFile[] ftpFilesList = ftpClient.listFiles();
for (FTPFile file : ftpFilesList) {
//文件名称包含乱码
String fileName = file.getName();
fileName = new String(fileName.getBytes("iso-8859-1"), "gb2312");//汉字转码
System.out.println("name:" + fileName);//文件名称
Date createDate = file.getTimestamp().getTime();//获取时间
System.out.println("time" + fmt.format(createDate));//文件创建时间
System.out.println("size" + file.getSize());//文件大小
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
ftpClient.disconnect();//断开与FTP服务器连接
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.文件上传
public class ftp {
public static void main(String[] args) {
//创建基于FTP协议访问的文件服务器的客户端对象
FTPClient ftpClient = new FTPClient();
//选择需要上传的文件,创建input输入流
try(FileInputStream in = new FileInputStream("d:\\text\\1.jpg")){
//连接服务器验证用户名密码
ftpClient.connect("127.0.0.1",21);//IP地址,端口号
ftpClient.login("admin","123456");//用户名,密码
//选择上传至的目录,切换目录操作
boolean isChange = ftpClient.changeWorkingDirectory("Admin");
//若无则创建目录
if (!isChange){
ftpClient.makeDirectory("Admin");//创建目录
//切换至目录
ftpClient.changeWorkingDirectory("Admin");
}
//上传文件至FTP服务器
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//二进制字节流上传
//参数1:FTP文件保存名称,参数2:本地文件输入流
boolean isStore = ftpClient.storeFile(System.currentTimeMillis()+"jpg",in);
System.out.println("上传成功?" + isStore);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//断开连接
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.文件下载
public class ftp {
public static void main(String[] args) {
//创建基于FTP协议访问的文件服务器的客户端对象
FTPClient ftpClient = new FTPClient();
//选择下载路径,创建output输出流
try (FileOutputStream out = new FileOutputStream("d:\\text\\"+System.currentTimeMillis()+"jpg")) {
//连接FTP服务器并验证用户信息
ftpClient.connect("127.0.0.1", 21);
ftpClient.login("Admin", "123456");
//切换至服务器的个人目录
boolean isChange = ftpClient.changeWorkingDirectory("User");
//下载文件
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//文件类型
boolean isStore = ftpClient.retrieveFile("2.jpg",out);//需要下载的文件名称
System.out.println("下载成功?"+isStore);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//断开连接
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
小结:
1.访问下载文件可通过浏览器访问FTP服务器的方式实现
2.文件上传下载以二进制流的方式进行,注意上传下载输入输出流的区分
向上攀爬的痛苦,终会在登顶时烟消云散
——ZQY