# **Java实现FTP服务器**
# **一、开发、运行环境说明**
1. 开发工具:IntelliJ IDEA
1. 开发环境: JDK1.8
1. 运行环境:IDEA(服务端) 和 windows 黑窗口(客户端)
# **二、系统实现的功能**:
(1)客户端通过Windows的命令行访问FTP服务器。
(2)FTP服务器可以并发地服务多个客户。
(3)实现对FTP命令user、pass、dir、get、upload五个命令的支持。
(4)对出现的问题或错误做出响应。
# **三、系统工程设计**
## 1.工程结构的截图:
![](img/Aspose.Words.9681c84d-94b5-4b06-ba54-6cb62e0fa4a3.003.png)
## 2.主要实现技术:
1. 通过Socket编程实现通信
1. 通过java线程池实现多线程并发访问
1. 使用了工厂设计模式
1. 对用户密码使用md5加密
## 3.关键代码实现:
```java
// 线程池工具类
public class ThreadUtil {
private static ThreadPool mThreadPool;
public static ThreadPool getThreadPool() {
if (mThreadPool == null) {
synchronized (ThreadUtil.class) {
if (mThreadPool == null) {
int cpuCount = Runtime.getRuntime().availableProcessors();// 获取cpu数量
System.out.println("cpu个数:" + cpuCount);
int threadCount = 10;
mThreadPool = new ThreadPool(threadCount, threadCount, 0l);
}
}
}
return mThreadPool;
}
// 线程池
public static class ThreadPool {
private int corePoolSize;// 核心线程数
private int maximumPoolSize;// 最大线程数
private long keepAliveTime;// 休息时间
private ThreadPoolExecutor executor;
private ThreadPool(int corePoolSize, int maximumPoolSize,
long keepAliveTime) {
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.keepAliveTime = keepAliveTime;
}
public void execute(Runnable r) {
if (executor == null) {
executor = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize, keepAliveTime, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(),
Executors.defaultThreadFactory(), new AbortPolicy());
// 参1:核心线程数;参2:最大线程数;参3:线程休眠时间;参4:时间单位;参5:线程队列;参6:生产线程的工厂;参7:线程异常处理策略
}
executor.execute(r);
}
// 取消任务
public void cancel(Runnable r) {
if (executor != null) {
// 从线程队列中移除对象
executor.getQueue().remove(r);
}
}
}
}
// user命令
public class UserCommmand implements BaseCommand {
private BufferedReader reader;
@Override
public void executeCommand(String userName, BufferedWriter writer, UserInfo userInfo) {
if (AccountUtil.hasUsername(userName)) {
System.out.println("The account is exist! "+userName);
try {
writer.write("\n331\r\n");
writer.flush();
userInfo.setUsername(userName);
//reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}else{
System.out.println("The account is not exist! "+userName);
try {
writer.write("501\r\n\n");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// pass命令,密码验证
public class PassCommand implements BaseCommand {
@Override
public void executeCommand(String passWord, BufferedWriter writer, UserInfo userInfo) {
String passWord2Md5 = Md5Util.encoder(passWord);
if (passWord2Md5.equals(AccountUtil.getPassword(userInfo.getUsername()))) {
System.out.println("密码正确"+passWord + ",md5密码:"+passWord2Md5);
try {
writer.write("\n 230 PWD is right!Welcome!\r\n");
writer.flush();
userInfo.setPassword(passWord2Md5);
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
writer.write("\n 530 Wrong PWD!\r\n");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// dir文件列表命令
public class DirCommand implements BaseCommand {
/**
* dir功能实现
* @param datas
* @param writer
* @param userInfo
*/
@Override
public void executeCommand(String datas, BufferedWriter writer, UserInfo userInfo) {
File file = new File(AccountUtil.getRootPath());
if (!file.isDirectory()) {
try {
writer.write("\n 210 The file is not exist\r\n");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}else{
//拼接文件目录字符串
StringBuffer dirList = new StringBuffer();
int count = 1;
for(String item:file.list()){
File itemFile = new File(file+File.separator+item);
String size = FileUtil.getFileSize(itemFile);
if (size.equals("")||size==null) {
size = "dir";
}else{
size += " file";
}
dirList.append(count+" "+item+" "+size);
dirList.append("\r\n");
count++;
}
try {
writer.write("\n 150 open ascii mode...\r\n");
writer.flush();
writer.write(dirList + "\r\n");
writer.write("220 transfer complete...\r\n");
writer.flush();
System.out.println(dirList.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 文件上传upload命令
public class UploadCommand implements BaseCommand {
/**
* 文件上传
* @param datas
* @param writer
* @param userInfo
*/
@Override
public void executeCommand(String datas, BufferedWriter writer, UserInfo userInfo) {
File file = new File(AccountUtil.getRootPath());
try{
writer.write("\n 150 Binary data connection\r\n");
writer.flush();
File lastFileName = new File(AccountUtil.getRootPath()+"/"+datas);
String name = AccountUtil.getRootPath()+datas;
for (String item:file.list()){
item = AccountUtil.getRootPath()+item;
//获取相同文件名
if (item.equals(name)){
//将文件名改成时间戳
File temp = new File(AccountUtil.getRootPath()+ Calendar.getInstance().getTimeInMillis()+"."+item.substring(item.lastIndexOf(".")+1));
lastFileName.renameTo(temp);
System.out.println(lastFileName);
}
}
RandomAccessFile inFile = new RandomAccessFile(lastFileName,"rw");
// 开始上传
Socket tempSocket = new Socket("127.0.0.1",25);
InputStream inSocket = tempSocket.getInputStream();
byte byteBuffer[] = new byte[1024];
int length;
while((length =inSocket.read(byteBuffer) )!= -1){
inFile.write(byteBuffer, 0, length);
}
System.out.println("transfer complete");
inFile.close();
inSocket.close();
tempSocket.close();
//传输结束
writer.write("\n226 upload success\r\n");
writer.flush();
}
catch(IOException e){
e.printStackTrace();
}
}
}
// 文件下载get命令
public class GetCommand implements BaseCommand {
@Override
public void executeCommand(String datas, BufferedWriter writer, UserInfo userInfo) {
File file = new File(AccountUtil.getRootPath()+File.separator+datas);
File rootFile = new File(System.getProperty("user.home")+File.separator);
File lastFileName = new File(System.getProperty("user.home")+File.separator+datas);
String name = System.getProperty("user.home")+"\\"+datas;
if (file.exists()) {
// 检测是否有相同的文件名
for (String item:rootFile.list()){
item = System.getProperty("user.home")+"\\"+item;
// 获取相同文件名
if (item.equals(name)){
// 如果有则改掉将文件名改成时间戳
File temp = new File(System.getProperty("
基于Java实现FTP服务器【100012631】
版权申诉
5星 · 超过95%的资源 42 浏览量
2023-06-05
16:38:52
上传
评论 1
收藏 407KB ZIP 举报
神仙别闹
- 粉丝: 2662
- 资源: 7639
最新资源
- IMG_20240425_120538.jpg
- My Complete Genome_6k Base-Pairs of Phenotype SNPs_Complete Raw Data.zip
- qt 的mqtt测试demo
- 移动应用开发教程-zip.zip
- mosquitto-2.018-install-windows-x64
- FTPServer FTP 服务器,绿色免安装,单文件
- 梦畅语音点名软件,上课点名
- 利用ADNI数据集和标签,在tensorflow框架上使用tensorlayer接口,通过架构u-net实现海马体的分割
- Kutools for Word v9.0 office word 插件
- 修复Windows 10 LTSC 2021资源占用率高
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈