开启FTP服务器(编程)

来源:互联网 发布:拦截wifi的软件 编辑:程序博客网 时间:2024/04/17 01:45

开启FTP服务器(编程)

  • 开启FTP服务器编程
    • 编程要点
    • 项目结构
    • 主要源码
    • 附言

编程要点

其实FTP的服务器编程很简单,只要两点,第一点就是资料的储备,这一点在我的另一篇博文FTP资料已经有了,第二点,也就是我摸索了很久的一点,那就是FTP的套路。
在使用window的cmd与我搭的ftp交互的过程中,我深深地感受到被套路,而且我还得主动去配合他的套路,比如说,我给出指令(红框)
这里写图片描述
你觉得我是自己可以随意输入吗?NO,不可以的,只有当响应码返回的时候,控制台才会开启某个输入给你输入。也就是说,如果服务器没有返回响应码,你是没办法输入的,就像这样
这里写图片描述
如果你编程的时候,不给他返回响应码,那么就没有输入的可能,那个光标只是让你看看,不能输入的。所以,每次都写执行的时候,都要先告诉控制台,给他相应的响应码。每条指令都有相应的响应码。

项目结构

这里写图片描述
E-R关系
这里写图片描述

主要源码

Command.java

package com.chen.model;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileFilter;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;import java.io.PrintStream;import java.net.Socket;import java.net.UnknownHostException;import java.util.ArrayList;public class Command {    private Socket socket;    private BufferedReader reader;    private BufferedWriter writer;    private User user = new User();    private String remoteHost;// 远程主机    private int remotePort;// 远程端口号    private static Socket dSocket = null;    private static String[] strs = new String[10];// 用来存储分解的指令//从中可以获得我们要的字符串    public Command(Socket socket, BufferedReader reader, BufferedWriter writer) {        super();        this.socket = socket;        this.reader = reader;        this.writer = writer;        response("220 Welcome to use.");    }    /**     * 服务器响应     *     * @param str     */    private void response(String str) {        try {            writer.write(str);            writer.newLine();            writer.flush();            System.out.println("服务响应:" + str);        } catch (IOException e) {            e.printStackTrace();        }    }    /**     * 打印信息     *     * @param dWriter     * @param str     */    private void printStr(BufferedWriter dWriter, String str) {        try {            dWriter.write(str);            dWriter.newLine();            dWriter.flush();            System.out.println("打印信息:" + str);        } catch (IOException e) {            e.printStackTrace();        }    }    public boolean command(String str) {        try {            strs = str.split(" ");        } catch (Exception e) {            // 今天是端午节,我却回不了家,没有粽子吃,我感到一股巨大的悲伤            // 而且更伤心的是 我还得打码            // 流泪            // 快瞎了            // 智商归零ing            strs[0] = str;// 如果没有可以切割的话说明就是单字符串的指令        }        System.out.println("用户命令:"+user.getUser()+" > "+ str);        str = strs[0];// 命令字        str = str.toUpperCase();        try {            switch (str) {            case "OPTS": {                response("332 User required.");// 用户名            }                break;            case "XMKD": {// 创建新文件                commandXMKD();            }            case "USER": {                user.setUser(strs[1]);// 装上名字                response("331 Password required.");            }                break;            case "PASS": {                commandPass();            }                break;            case "QUIT": {                response("221 thank for use.");                user.setWorkDir("");            }                break;            case "PORT": {// port IP 地址和两字节的端口 ID                commandPORT();            }// DIR 命令 //接下来执行List命令                break;            case "LIST": {// dir命令                commandList();            }                break;            case "CWD": {// CD 命令                commandCWD();            }                break;            case "RETR": {// GET 命令 :下载文件                commandRETR();            }                break;            case "STOR": {// SEND 命令:上传文件                commandSTOR();            }                break;            default: {                response("500 command param error.");            }                break;            }        } catch (Exception e) {            response("500 command param error.");// 错误        }        return true;    }    private void commandXMKD() {        String mkdirFile = user.getWorkDir() + "/" + strs[1];        File file = new File(mkdirFile);        if (!file.exists()) {            file.mkdir();        }    }    /**     * 上传文件     */    private void commandSTOR() {        String oldFileUrl = "";        if (strs[1].contains(user.getOriDir())) {// 万一客户直接就把全路径写了呢            oldFileUrl = strs[1];        } else {            oldFileUrl = user.getWorkDir() + "/" + strs[1];// 请求文件的全路径        }        BufferedOutputStream bos = null;        BufferedInputStream bis = null;        // 上传文件        try {            dSocket = new Socket(remoteHost, remotePort);            bos = new BufferedOutputStream(new FileOutputStream(oldFileUrl));            bis = new BufferedInputStream(dSocket.getInputStream());// 客户端塞过来的流            // 我就吃吃吃            byte[] buf = new byte[1024];            int l = 0;            while ((l = bis.read(buf, 0, 1024)) != -1) {                bos.write(buf, 0, l);            }            response("150 Opening connection for " + oldFileUrl);            response("226 Transfer complete.");        } catch (Exception e) {            e.printStackTrace();            response("550 The system cannot find the path specified.");        } finally {            try {                bis.close();                bos.close();                dSocket.close();                dSocket = null;            } catch (IOException e) {                e.printStackTrace();            }        }        response("226 Transfer complete.");    }    /**     * 下载文件     */    private boolean commandRETR() {        BufferedInputStream fin = null;        PrintStream dout = null;        String oldFileUrl = user.getWorkDir() + "/" + strs[1];// 请求文件的全路径        File file = new File(strs[1]);        if (!file.exists()) {// 万一用户用的是全路径            file = new File(oldFileUrl);            if (!file.exists()) { // 万一用的是缺省呢                response("550 The system cannot find the file specified.");// 没有该文件                return false;            }        }        // 下载文件        try {            response("150 Opening  connection for " + oldFileUrl);            dSocket = new Socket(remoteHost, remotePort);            fin = new BufferedInputStream(new FileInputStream(oldFileUrl));            dout = new PrintStream(dSocket.getOutputStream(), true);            byte[] buf = new byte[1024];            int l = 0;            while ((l = fin.read(buf, 0, 1024)) != -1) {                dout.write(buf, 0, l);// 往dataSocket死命地写 没有粽子吃的悲伤                                        // 反正客户端会收到悲伤,收不到我的注释            }            response("226 Transfer complete.");        } catch (Exception e) {            e.printStackTrace();            response("550 The system cannot find the path specified.");            return false;        } finally {            try {                fin.close();                dout.close();                dSocket.close();                dSocket = null;            } catch (IOException e) {                e.printStackTrace();            }        }        return true;    }    /**     * 用来进入某个文件     */    private boolean commandCWD() {        // 怎么说呢,其实很简单吧,应该就是把用户文件工作区拼上请求字符        if ("/".equals(strs[1]) || "\\".equals(strs[1])) {            user.setWorkDir(user.getOriDir());            response("250 Requested file action okay,the directory is "                    + user.getWorkDir());            return true;        }        // 判断文件夹存不存在        File workDir = new File(user.getWorkDir());        File[] files = workDir.listFiles(new FileFilter() {            @Override            public boolean accept(File paramFile) {                if (paramFile.getName().contains("."))                    return false;                return true;            }        });// 文件夹的文件夹        boolean flag = false;        for (File f : files) {            if (f.getName().equals(strs[1])) {                flag = true;                break;            }        }        if (flag) {            user.setWorkDir(user.getWorkDir() + "/" + strs[1]);            response("250 Requested file action okay,the directory is "                    + user.getWorkDir());        } else {            response("550 The directory does not exists");        }        response("250 CWD command successful.");        return true;    }    /**     * Pass 命令:验证密码 strs[1]:命令字符串的第二个 一般是参数     */    private void commandPass() {        // 检查 用户是否存在        boolean isUser = false;        ArrayList<User> users = User.getUsers();        for (User u : users) {            if (user.getUser().equals(u.getUser())                    && strs[1].equals(u.getPassword())) {                isUser = true;                user = u;// 整个user都赋值过去                break;            }        }        if (isUser) {// 是我们的用户            response("230 User logged in.");        } else {// 非法用户            response("530 Not logged in,you account is wrong.");        }    }    /**     * post 请求命令:     */    private void commandPORT() {        String[] temp = strs[1].split(",");        remoteHost = temp[0] + "." + temp[1] + "." + temp[2] + "." + temp[3];        String port1 = null;        String port2 = null;        if (temp.length == 6) {            port1 = temp[4];            port2 = temp[5];        } else {            port1 = "0";            port2 = temp[4];        }        remotePort = Integer.parseInt(port1) * 256 + Integer.parseInt(port2);        response("200 PORT command successful.");    }    /**     * List 命令:显示所有的文件     */    private void commandList() {        response("150 Data connection already open; Transfer starting.");        OutputStreamWriter dStream = null;        BufferedWriter dWriter = null;        try {            dSocket = new Socket(remoteHost, remotePort);            dStream = new OutputStreamWriter(dSocket.getOutputStream(),"gb2312");            dWriter = new BufferedWriter(dStream);            // 要输出的数据            File file = new File(user.getWorkDir());            File[] files = file.listFiles();            String fMess;// 文件信息            String tab = "     ";// 5个空格            for (File f : files) {                fMess = TimeDealer.timeFormat(f.lastModified())// 时间                        + tab // 格式                        + (f.isFile() ? tab : "<DIR>") + tab // 格式                        + f.getName();                printStr(dWriter, fMess);            }        } catch (UnknownHostException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                dWriter.close();                dStream.close();                dSocket.close();                dSocket = null;            } catch (IOException e) {                e.printStackTrace();            }        }        response("226 transfer complete");    }}

附言

以上就是所有的总结了,如果有任何问题,欢迎给我留言。

0 0
原创粉丝点击