亚洲欧美日韩综合系列在线_91精品人妻一区二区_欧美大肥婆一级特大AA片_九色91视频免费观看_亚洲综合国产精品_av中文字幕在线不卡_久久精品色综合网_看黄色视频的软件_无卡无码高清中文字幕码2024_亚洲欧美日韩天堂网

開啟FTP服務器(編程)

來源:CHEN俊銘 發(fā)布時間:2018-11-21 15:27:32 閱讀量:1375

開啟FTP服務器(編程)

開啟FTP服務器編程

編程要點

項目結構

主要源碼

附言

編程要點

其實FTP的服務器編程很簡單,只要兩點,第一點就是資料的儲備,這一點在我的另一篇博文FTP資料已經(jīng)有了,第二點,也就是我摸索了很久的一點,那就是FTP的套路。 

在使用window的cmd與我搭的ftp交互的過程中,我深深地感受到被套路,而且我還得主動去配合他的套路,比如說,我給出指令(紅框) 


你覺得我是自己可以隨意輸入嗎?NO,不可以的,只有當響應碼返回的時候,控制臺才會開啟某個輸入給你輸入。也就是說,如果服務器沒有返回響應碼,你是沒辦法輸入的,就像這樣 


如果你編程的時候,不給他返回響應碼,那么就沒有輸入的可能,那個光標只是讓你看看,不能輸入的。所以,每次都寫執(zhí)行的時候,都要先告訴控制臺,給他相應的響應碼。每條指令都有相應的響應碼。


項目結構

 

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) {

            // 今天是端午節(jié),我卻回不了家,沒有粽子吃,我感到一股巨大的悲傷

            // 而且更傷心的是 我還得打碼

            // 流淚

            // 快瞎了

            // 智商歸零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": {// 創(chuàng)建新文件

                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 地址和兩字節(jié)的端口 ID

                commandPORT();

            }// DIR 命令 //接下來執(zhí)行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() {

        // 怎么說呢,其實很簡單吧,應該就是把用戶文件工作區(qū)拼上請求字符

        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]:命令字符串的第二個 一般是參數(shù)

     */

    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);


            // 要輸出的數(shù)據(jù)

            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");


    }

}

--------------------- 



標簽: 服務器搭建
分享:
評論:
你還沒有登錄,請先