FTP协议Java实现
参照文章 https://blog.csdn.net/qq_16038125/article/details/72851142 讲的原理
具体实现参考
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
搭建ftp命令
# 安装vsftpd
sudo apt-get install vsftpd
vsftpd -version
# 新建ftp目录
mkdir /home/ftp
# 新增用户
sudo useradd -d /home/ftp -s /bin/bash ftpname
passwd ftpname
# 修改配置
vi /etc/vsftpd.conf
# 修改配置-找到这个配置,去掉注释修改成YES
userlist_enable=YES
# 启动服务
service vsftpd start
被动模式实现
import javax.net.SocketFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 被动模式的FTP
*/
public class FtpPassiveTest {
public static void main(String[] args) throws IOException {
SocketFactory socketFactory = SocketFactory.getDefault();
Socket socket = socketFactory.createSocket();
socket.connect(new InetSocketAddress("192.168.72.132", 21), 10000);
socket.setSoTimeout(10000);
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
// 预读取
read(inputStream);
// 发送命令
outputStream.write("USER ftpname\r\n".getBytes());outputStream.flush();
read(inputStream);
outputStream.write("PASS 123456\r\n".getBytes());outputStream.flush();
read(inputStream);
outputStream.write("PASV\r\n".getBytes());outputStream.flush();
String passiveMode = read(inputStream);
Pattern parmsPat = Pattern.compile("(\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}),(\\d{1,3}),(\\d{1,3})");
Matcher matcher = parmsPat.matcher(passiveMode);
matcher.find();
String replace = matcher.group(1).replace(',', '.');
int oct1 = Integer.parseInt(matcher.group(2));
int oct2 = Integer.parseInt(matcher.group(3));
int passivePort = (oct1 << 8) | oct2;
System.out.println(replace + " " + passivePort);
Socket lsSocket = socketFactory.createSocket();
lsSocket.connect(new InetSocketAddress(replace, passivePort));
outputStream.write("LIST\r\n".getBytes());
outputStream.flush();
read(inputStream);
read2(lsSocket.getInputStream());
}
public static String read(InputStream inputStream) throws IOException {
byte[] buffer = new byte[10240];
int read = inputStream.read(buffer);
String result = new String(Arrays.copyOfRange(buffer, 0, read));
System.out.println(result);
return result;
}
public static String read2(InputStream inputStream) throws IOException {
byte[] buffer = new byte[200];
int read = inputStream.read(buffer);
String result = new String(Arrays.copyOfRange(buffer, 100, read));
System.out.println(result);
return result;
}
}
主动模式实现
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
/**
* 主动模式的FTP
*/
public class FtpActiveTest {
public static void main(String[] args) throws IOException {
SocketFactory socketFactory = SocketFactory.getDefault();
Socket socket = socketFactory.createSocket();
socket.connect(new InetSocketAddress("192.168.72.132", 21), 10000);
socket.setSoTimeout(10000);
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
// 预读取
read(inputStream);
// 发送命令
outputStream.write("USER ftpname\r\n".getBytes());outputStream.flush();
read(inputStream);
outputStream.write("PASS 123456\r\n".getBytes());outputStream.flush();
read(inputStream);
ServerSocketFactory serverSocketFactory = ServerSocketFactory.getDefault();
ServerSocket serverSocket = serverSocketFactory.createServerSocket(0, 1, socket.getLocalAddress());
// 告诉ftp服务器,我本地socket套接字是个啥
String hostAddress = socket.getLocalAddress().getHostAddress();
String port = port(hostAddress, serverSocket.getLocalPort());
String cmd = "PORT " + port + "\r\n";
outputStream.write(cmd.getBytes());outputStream.flush();
read(inputStream);
// 向ftp服务器发送列出列表指令
outputStream.write("LIST /home/ftp\r\n".getBytes());outputStream.flush();
read(inputStream);
// 获取ftp服务器的套接字 并接受ftp服务器套接字的返回
Socket accept = serverSocket.accept();
read(accept.getInputStream());
serverSocket.close();
}
public static String port(String hostAddress, int port) throws IOException
{
int num;
StringBuilder info = new StringBuilder(24);
info.append(hostAddress.replace('.', ','));
num = port >>> 8;
info.append(',');
info.append(num);
info.append(',');
num = port & 0xff;
info.append(num);
return info.toString();
}
public static void read(InputStream inputStream) throws IOException {
byte[] buffer = new byte[10240];
int read = inputStream.read(buffer);
String result = new String(Arrays.copyOfRange(buffer, 0, read));
System.out.println(result);
}
}