[JAVA服务器]用Java实现FTP服务器

[JAVA服务器]用Java实现FTP服务器

用Java实现FTP服务器

FTP 命令

  FTP 的主要操作都是基于各种命令基础之上的。常用的命令有:

  ◆ 设置传输模式,它包括ASCⅡ(文本) 和BINARY 二进制模式;

  ◆ 目录操作,改变或显示远程计算机的当前目录(cd、dir/ls 命令);

  ◆ 连接操作,open命令用于建立同远程计算机的连接;close命令用于关闭连接;

  ◆ 发送操作,put命令用于传送文件到远程计算机;mput 命令用于传送多个文件到远程计算机;

  ◆ 获取操作,get命令用于接收一个文件;mget命令用于接收多个文件。

  ◆ 目录操作,改变或显示远程计算机的当前目录(cd、dir/ls 命令);

  ◆ 连接操作,open命令用于建立同远程计算机的连接;close命令用于关闭连接;

  ◆ 发送操作,put命令用于传送文件到远程计算机;mput 命令用于传送多个文件到远程计算机;

  ◆ 获取操作,get命令用于接收一个文件;mget命令用于接收多个文件。

 

import java.io.*;
import java.net.*;
import java.util.*;

public class FtpServer
{
 private Socket socketClient;
 private int counter;
 public static String initDir;
 public static ArrayList users = new ArrayList();
 public static ArrayList usersInfo = new ArrayList();
 
 public FtpServer()
 {
  FtpConsole fc = new FtpConsole();
  fc.start();
  loadUsersInfo();
  int counter = 1;
  int i = 0;
  try
  {

   //监听21号端口
   ServerSocket s = new ServerSocket(21);
   for(;;)
   {
    //接受客户端请求
    Socket incoming = s.accept();
    BufferedReader in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
       PrintWriter out = new PrintWriter(incoming.getOutputStream(),true);
    out.println("220 Service ready for new user"+counter);

    //创建服务线程
    FtpHandler h = new FtpHandler(incoming,i);
    h.start();
    users.add(h);
    counter++;
    i++;
   }
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
  
 } // FtpServer() end
 
 public void loadUsersInfo()
 {
  String s = getClass().getResource("user.cfg").toString();
  s = s.substring(6,s.length());
  int p1 = 0;
  int p2 = 0;
  if(new File(s).exists())
  {
   try
   {
    BufferedReader fin = new BufferedReader(new InputStreamReader(new FileInputStream(s)));
    String line;
    String field;
    
    
    int i = 0;
    while((line = fin.readLine())!=null)
    {
     UserInfo tempUserInfo = new UserInfo();
     p1 = 0;
     p2 = 0;
     i = 0;
     if(line.startsWith("#"))
      continue;
     while((p2 = line.indexOf("|",p1))!=-1)
     {
      field = line.substring(p1,p2);
      p2 = p2 +1;
      p1 = p2;
      switch(i)
      {
       case 0:
        tempUserInfo.user = field;
        //System.out.println(tempUserInfo.user);
        break;
       case 1:
        tempUserInfo.password = field;
        //System.out.println(tempUserInfo.password);
        break;
       case 2:
        tempUserInfo.workDir = field;
        //System.out.println(tempUserInfo.workDir);
        break;
      }
      i++;
     } //while((p2 = line.indexOf("|",p1))!=-1) end
     usersInfo.add(tempUserInfo);
    }//while((line = fin.readLine())!=null) end
    fin.close();
   }
   catch(Exception e)
   {
    e.printStackTrace();
   }
  }//if(new File(s).exists()) end
 }// loadUsersInfo() end
 
 public static void main(String[] args)
 {
  if(args.length != 0)
  {
   initDir = args[0];
  }
  else
  {
   initDir = "c:/"; 
  }
  FtpServer ftpServer = new FtpServer();
  
 } // main end
  
}

class FtpHandler extends Thread
{
 Socket csocket;
 Socket dsocket;
 int id;
 String cmd = "";
 String param = "";
 String user;
 String remoteHost = " ";
 int remotePort = 0;
 String dir = FtpServer.initDir;
 String rootdir = "c:/";
 int state = 0;
 String reply;
 PrintWriter out;
 int type = 0;
 String requestfile = "";
 boolean isrest = false;
 
 int parseInput(String s)
 {
  int p = 0;
  int i = -1;
  p = s.indexOf(" ");
  if(p == -1)
   cmd = s;
  else
   cmd = s.substring(0,p);
  
  if(p >= s.length() || p ==-1)
   param = "";
  else
   param = s.substring(p+1,s.length());
  cmd = cmd.toUpperCase();
  
  if(cmd.equals("USER"))
    i = 1;
  if(cmd.equals("PASS"))
    i = 2;
  if(cmd.equals("ACCT"))
    i = 3;
    if(cmd.equals("CDUP"))
    i = 4;
  if(cmd.equals("SMNT"))
    i = 5;
  if(cmd.equals("CWD"))
    i = 6;
  if(cmd.equals("QUIT"))
    i = 7;
    if(cmd.equals("REIN"))
    i = 8;
  if(cmd.equals("PORT"))
    i = 9;
  if(cmd.equals("PASV"))
    i = 10;
  if(cmd.equals("TYPE"))
    i = 11;
    if(cmd.equals("STRU"))
    i = 12;
  if(cmd.equals("MODE"))
    i = 13;
  if(cmd.equals("RETR"))
    i = 14;
  if(cmd.equals("STOR"))
    i = 15;
    if(cmd.equals("STOU"))
    i = 16;
  if(cmd.equals("APPE"))
    i = 17;
  if(cmd.equals("ALLO"))
    i = 18;
  if(cmd.equals("REST"))
    i = 19;
    if(cmd.equals("RNFR"))
    i = 20;
  if(cmd.equals("RNTO"))
    i = 21;
  if(cmd.equals("ABOR"))
    i = 22;
  if(cmd.equals("DELE"))
    i = 23;
    if(cmd.equals("RMD"))
    i = 24;
  if(cmd.equals("XMKD"))
    i = 25;    
  if(cmd.equals("MKD"))
    i = 25;
  if(cmd.equals("PWD"))
    i = 26;
  if(cmd.equals("LIST"))
    i = 27;
    if(cmd.equals("NLST"))
    i = 28;
  if(cmd.equals("SITE"))
    i = 29;
  if(cmd.equals("SYST"))
    i = 30;
  if(cmd.equals("HELP"))
    i = 31;
    if(cmd.equals("NOOP"))
    i = 32;
  if(cmd.equals("XPWD"))
    i = 33;
  return i;
 }//parseInput() end
 
 int validatePath(String s)
 {
  File f = new File(s);
  if(f.exists() && !f.isDirectory())
  {
   String s1 = s.toLowerCase();
   String s2 = rootdir.toLowerCase();
   if(s1.startsWith(s2))
    return 1;
   else
    return 0;
  }
  f = new File(addTail(dir)+s);
  if(f.exists() && !f.isDirectory())
  {
   String s1 = (addTail(dir)+s).toLowerCase();
   String s2 = rootdir.toLowerCase();
   if(s1.startsWith(s2))
    return 2;
   else
    return 0;
  }
  return 0;
 }// validatePath() end
 
 boolean checkPASS(String s)
 {
  for(int i = 0; i<FtpServer.usersInfo.size();i++)
  {
   if(((UserInfo)FtpServer.usersInfo.get(i)).user.equals(user) &&
    ((UserInfo)FtpServer.usersInfo.get(i)).password.equals(s))
   {
    rootdir = ((UserInfo)FtpServer.usersInfo.get(i)).workDir;
    dir = ((UserInfo)FtpServer.usersInfo.get(i)).workDir;
    return true;
   }
  }
  return false;
 }// checkPASS() end

 boolean commandUSER()
 {
  if(cmd.equals("USER"))
  {
   reply = "331 User name okay, need password";
   user = param;
     state = FtpState.FS_WAIT_PASS;
   return false;
  }
  else
  {
   reply = "501 Syntax error in parameters or arguments";
   return true;
  }

 }//commandUser() end

 boolean commandPASS()
 {
  if(cmd.equals("PASS"))
  {
   if(checkPASS(param))
   {
    reply = "230 User logged in, proceed";
    state = FtpState.FS_LOGIN;
    System.out.println("Message: user "+user+" Form "+remoteHost+"Login");
    System.out.print("->");
    return false;
   }
   else
   {
    reply = "530 Not logged in";
    return true;
   }
  }
  else
  {
   reply = "501 Syntax error in parameters or arguments";
   return true;
  }

 }//commandPass() end

 void errCMD()
 {
  reply = "500 Syntax error, command unrecognized";
 } 
 
 boolean commandCDUP()
 {
  dir = FtpServer.initDir;
  File f = new File(dir);
  if(f.getParent()!=null &&(!dir.equals(rootdir)))
  {
   dir = f.getParent();
   reply = "200 Command okay";
  }
  else
  {
   reply = "550 Current directory has no parent";
  }
  
  return false;
 }// commandCDUP() end

 boolean commandCWD()
 {
  File f = new File(param);
  String s = "";
  String s1 = "";
  if(dir.endsWith("/"))
   s = dir;
  else
   s = dir + "/";
  File f1 = new File(s+param);
  
  if(f.isDirectory() && f.exists())
  {
   if(param.equals("..") || param.equals("..//"))
   {
    if(dir.compareToIgnoreCase(rootdir)==0)
    {
     reply = "550 The directory does not exists";
     //return false;
    }
    else
    {
     s1 = new File(dir).getParent();
     if(s1!=null)
     {
      dir = s1;
      reply = "250 Requested file action okay, directory change to "+dir;
     }
     else
      reply = "550 The directory does not exists";
    }
   }
   else if(param.equals(".") || param.equals(".//"))
   {
   }
   else
   {
    dir = param;
    reply = "250 Requested file action okay, directory change to "+dir;
   }  
  }
  else if(f1.isDirectory() && f1.exists())
  {
   dir = s+param;
   reply = "250 Requested file action okay, directory change to "+dir;
  }
  else
   reply = "501 Syntax error in parameters or arguments";
  
  return false;
 } // commandCDW() end

 boolean commandQUIT()
 {
  reply = "221 Service closing control connection";
  return true;
 }// commandQuit() end

 boolean commandPORT()
 {
  int p1 = 0;
  int p2 = 0;
  int[] a = new int[6];
  int i = 0;
  try
  {
   while((p2 = param.indexOf(",",p1))!=-1)
   {
     a[i] = Integer.parseInt(param.substring(p1,p2));
     p2 = p2+1;
     p1 = p2;
     i++;
   }
   a[i] = Integer.parseInt(param.substring(p1,param.length()));
  }
  catch(NumberFormatException e)
  {
   reply = "501 Syntax error in parameters or arguments";
   return false;
  }
  
  remoteHost = a[0]+"."+a[1]+"."+a[2]+"."+a[3];
  remotePort = a[4] * 256+a[5];
  reply = "200 Command okay";
  return false;
 }//commandPort() end 
 
 boolean commandLIST()
 {
  try
  {
   dsocket = new Socket(remoteHost,remotePort,InetAddress.getLocalHost(),20);
   PrintWriter dout = new PrintWriter(dsocket.getOutputStream(),true);
   if(param.equals("") || param.equals("LIST"))
   {
    out.println("150 Opening ASCII mode data connection for /bin/ls. ");
    File f = new File(dir);
    String[] dirStructure = f.list();
    String fileType;
    for(int i =0; i<dirStructure.length;i++)
    {
     if(dirStructure[i].indexOf(".")!=-1)
     {
      fileType = "- ";
     }
     else
     {
      fileType = "d ";
     }
     dout.println(fileType+dirStructure[i]);
    }
   }
   dout.close();
   dsocket.close();
   reply = "226 Transfer complete !";
  }
  catch(Exception e)
  {
   e.printStackTrace();
   reply = "451 Requested action aborted: local error in processing";
   return false;
  }
  
  return false;
 }// commandLIST() end

 boolean commandTYPE()
 {
  if(param.equals("a"))
  {
   type = FtpState.FTYPE_ASCII;
   reply = "200 Command okay Change to ASCII mode";
  }
  else if(param.equals("i"))
  {
   type = FtpState.FTYPE_IMAGE;
   reply = "200 Command okay Change to BINARY mode";
  }
  else
   reply = "504 Command not implemented for that parameter";
   
  return false;
 }//commandTYPE() end

 boolean commandRETR()
 {
  requestfile = param;
  File f =  new File(requestfile);
    if(!f.exists())
  {
     f = new File(addTail(dir)+param);
   if(!f.exists())
   {
       reply = "550 File not found";
       return  false;
   }
   requestfile = addTail(dir)+param;
  }
 
    if(isrest)
  {
    
  }
  else
  {
    if(type==FtpState.FTYPE_IMAGE)
   {
    try
    {
     out.println("150 Opening Binary mode data connection for "+ requestfile);
     dsocket = new Socket(remoteHost,remotePort,InetAddress.getLocalHost(),20);
        BufferedInputStream  fin = new BufferedInputStream(new FileInputStream(requestfile));
       PrintStream 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);
     }
      fin.close();
         dout.close();
      dsocket.close();
      reply ="226 Transfer complete !";

    }
    catch(Exception e)
    {
     e.printStackTrace();
     reply = "451 Requested action aborted: local error in processing";
     return false;
    }

   }
   if(type==FtpState.FTYPE_ASCII)
   {
      try
    {
     out.println("150 Opening ASCII mode data connection for "+ requestfile);
     dsocket = new Socket(remoteHost,remotePort,InetAddress.getLocalHost(),20);
        BufferedReader  fin = new BufferedReader(new FileReader(requestfile));
       PrintWriter dout = new PrintWriter(dsocket.getOutputStream(),true);
     String s;
     while((s=fin.readLine())!=null)
     {
         dout.println(s);
     }
      fin.close();
         dout.close();
      dsocket.close();
      reply ="226 Transfer complete !";
    }
    catch(Exception e)
    {
     e.printStackTrace();
     reply = "451 Requested action aborted: local error in processing";
     return false;
    }
   }
  }
    return false;

 }//commandRETR() end

 boolean commandSTOR()
 {
  if(param.equals(""))
  {
   reply = "501 Syntax error in parameters or arguments";
   return false;
  }
  requestfile = addTail(dir)+param;
  if(type == FtpState.FTYPE_IMAGE)
  {
   try
   {
    out.println("150 Opening Binary mode data connection for "+ requestfile);
    dsocket = new Socket(remoteHost,remotePort,InetAddress.getLocalHost(),20);
    BufferedOutputStream fout = new BufferedOutputStream(new FileOutputStream(requestfile));
    BufferedInputStream din = new BufferedInputStream(dsocket.getInputStream());
    byte[] buf = new byte[1024];
    int l = 0;
    while((l = din.read(buf,0,1024))!=-1)
    {
     fout.write(buf,0,l);
    }//while()
    din.close();
    fout.close();
    dsocket.close();
    reply = "226 Transfer complete !";
   }
   catch(Exception e)
   {
    e.printStackTrace();
    reply = "451 Requested action aborted: local error in processing";
    return false;
   }
  }
  if(type == FtpState.FTYPE_ASCII)
  {
   try
   {
    out.println("150 Opening ASCII mode data connection for "+ requestfile);
    dsocket = new Socket(remoteHost,remotePort,InetAddress.getLocalHost(),20);
    PrintWriter fout = new PrintWriter(new FileOutputStream(requestfile));
    BufferedReader din = new BufferedReader(new InputStreamReader(dsocket.getInputStream()));
    String line;
    while((line = din.readLine())!=null)
    {
     fout.println(line);     
    }
    din.close();
    fout.close();
    dsocket.close();
    reply = " 226 Transfer complete !";
   }
   catch(Exception e)
   {
    e.printStackTrace();
    reply = "451 Requested action aborted: local error in processing";
    return false;
   }
  }
  return false;
 }//commandSTOR() end
 
 boolean commandPWD()
 {
  reply = "257 " + dir + " is current directory.";
  return false;
 }//commandPWD() end
 
 boolean commandNOOP()
 {
  reply = "200 OK.";
  return false;
 }//commandNOOP() end
 
 boolean commandABOR()
 {
  try
  {
   dsocket.close();
  }
  catch(Exception e)
  {
   e.printStackTrace();
   reply = "451 Requested action aborted: local error in processing";
   return false;
  }
  reply = "421 Service not available, closing control connection";
  return false;
 }//commandABOR() end
 
 boolean commandDELE()
 {
  int i = validatePath(param);
  if(i == 0)
  {
   reply = "550 Request action not taken";
      return false;
  }
  if(i == 1)
     {
      File f = new File(param);
   f.delete();
     }
  if(i == 2)
  {
   File f= new File(addTail(dir)+param);
   f.delete();
  }
  
  reply = "250 Request file action ok,complete";
  return false;

 }//commandDELE() end

 boolean commandMKD()
 {
  String s1 = param.toLowerCase();
  String s2 = rootdir.toLowerCase();
  if(s1.startsWith(s2))
  {
   File f = new File(param);
   if(f.exists())
   {
    reply = "550 Request action not taken";
    return false;
   }
   else
   {
    f.mkdirs();
    reply = "250 Request file action ok,complete";
   }
  }
  else
  {
   File f = new File(addTail(dir)+param);
   if(f.exists())
   {
    reply = "550 Request action not taken";
    return false;
   }
   else
   {
    f.mkdirs();
    reply = "250 Request file action ok,complete";
   }
  }
  
  return false;
 }//commandMKD() end

 String addTail(String s)
 {
  if(!s.endsWith("/"))
   s = s + "/";
  return s;
 }
 
 public FtpHandler(Socket s,int i)
 {
  csocket = s;
  id = i; 
 }
 
 public void run()
 {
  String str = "";
  int parseResult;
  
  try
  {
   BufferedReader in = new BufferedReader
        (new InputStreamReader(csocket.getInputStream()));
   out = new PrintWriter
        (csocket.getOutputStream(),true);
   state  = FtpState.FS_WAIT_LOGIN;
   boolean finished = false;
   while(!finished)
   {
    str = in.readLine();
    if(str == null) finished = true;
    else
    {
     parseResult = parseInput(str);
     System.out.println("Command:"+cmd+" Parameter:"+param);
     System.out.print("->");
     switch(state)
     {
      case FtpState.FS_WAIT_LOGIN:
        finished = commandUSER();
        break;
      case FtpState.FS_WAIT_PASS:
        finished = commandPASS();
        break;
      case FtpState.FS_LOGIN:
      {
       switch(parseResult)
       {
        case -1:
         errCMD();
         break;
        case 4:
         finished = commandCDUP();
         break;
        case 6:
         finished = commandCWD();
         break;
        case 7:
         finished = commandQUIT();
         break;
        case 9:
         finished = commandPORT();
         break;
        case 27:
         finished = commandLIST();
         break;
        case 11:
         finished = commandTYPE();
         break;
        case 14:
         finished = commandRETR();
         break;
        case 15:
         finished = commandSTOR();
         break;
        case 26:
        case 33:
         finished = commandPWD();
         break;
        case 32:
         finished = commandNOOP();
         break;
        case 22:
         finished = commandABOR();
         break;
        case 23:
         finished = commandDELE();
         break;
        case 25:
         finished = commandMKD();
         break;
        
       }// switch(parseResult) end
      }// case FtpState.FS_LOGIN: end
       break;
      

     }// switch(state) end
    } // else
    out.println(reply);
   } //while
   csocket.close();
  } //try
  catch(Exception e)
  {
   e.printStackTrace();
  }
 }
}

class FtpConsole extends Thread
{
 BufferedReader cin;
 String conCmd;
 String conParam;
 
 int consoleQUIT()
 {
  System.exit(0);
  return 0;
 }//consoleQUIT() end
 
 boolean consoleLISTUSER()
 {
  System.out.println("username /t/t workdirectory");
  for(int i = 0 ; i<FtpServer.usersInfo.size();i++)
  {
   System.out.println(((UserInfo)FtpServer.usersInfo.get(i)).user+" /t/t/t "+((UserInfo)FtpServer.usersInfo.get(i)).workDir);
  }
  return false;
 }//consoleLISTUSER() end
 
 boolean consoleLIST()
 {
  int i = 0;
    for(i=0;i<FtpServer.users.size();i++)
  {
   System.out.println((i+1)+":"+((FtpHandler)(FtpServer.users.get(i))).user + " From " +((FtpHandler)(FtpServer.users.get(i))).csocket.getInetAddress().toString());
  }

       return false;
 }//consoleLIST() end
 
 boolean validateUserName(String s)
 {
  for(int i = 0 ; i<FtpServer.usersInfo.size();i++)
  {
   if(((UserInfo)FtpServer.usersInfo.get(i)).user.equals(s))
    return false; 
  }
  return true;
 }//validateUserName() end

 boolean consoleADDUSER()
 {
  System.out.print("please enter username:");
  try
  {
   cin = new BufferedReader(new InputStreamReader(System.in));
   UserInfo tempUserInfo = new UserInfo();
   String line = cin.readLine();
   if(line != "")
   {
    if(!validateUserName(line))
    {
     System.out.println("user "+line+" already exists!");
     return false;
    }
   }
   else
   {
    System.out.println("username cannot be null!");
    return false;
   }
   tempUserInfo.user = line;
   System.out.print("enter password :");
   line = cin.readLine();
   if(line != "")
    tempUserInfo.password = line;
   else
   {
    System.out.println("password cannot be null!");
    return false;
   }
   System.out.print("enter the initial directory: ");
   line = cin.readLine();
   if(line != "")
   {
    File f = new File(line);
    if(!f.exists())
     f.mkdirs();
    tempUserInfo.workDir = line;
   }
   else
   {
    System.out.println("the directory cannot be null!");
    return false;
   }
   FtpServer.usersInfo.add(tempUserInfo);
   saveUserInfo();
  }
  catch(Exception e)
  {
   e.printStackTrace();
   return false;
  }
  return false;
 }//consoleADDUSER() end
 
 void saveUserInfo()
 {
  String s = "";
  try
  {
   BufferedWriter fout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("user.cfg")));
   for(int i = 0; i < FtpServer.usersInfo.size();i++)
   {
    s = ((UserInfo)FtpServer.usersInfo.get(i)).user+"|"+((UserInfo)FtpServer.usersInfo.get(i)).password+"|"+((UserInfo)FtpServer.usersInfo.get(i)).workDir+"|";
    fout.write(s);
    fout.newLine();
   }
   fout.close();
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
 }//saveUserInfo() end
 
 boolean consoleDELUSER()
 {
  String s = "";
  //System.out.println(conParam);
  if(conParam.equals(""))
  {
   System.out.println("usage:deluser username");
   return false;
  }
  for(int i=0;i<FtpServer.usersInfo.size();i++)
  {
   s = ((UserInfo)FtpServer.usersInfo.get(i)).user;
   if(s.equals(conParam))
   {
    System.out.println("User "+conParam+" deleted");
                FtpServer.usersInfo.remove(i);
    saveUserInfo();
    return false;
   }
  }
  System.out.println("User "+conParam+" not exists");     
  return false;

 }//consoleDELUSER() end
 
 boolean consoleHELP()
 {
  if(conParam.equals(""))
  {
   System.out.println("adduser :add new user");
   System.out.println("deluser <username> :delete a user");
   System.out.println("quit  :quit");
   System.out.println("list  :list all user connect to server");
   System.out.println("listuser : list all account of this server");
   System.out.println("help :show  this help");
  }
  else if(conParam.equals("adduser"))
   System.out.println("adduser :add new user");
  else if(conParam.equals("deluser"))
   System.out.println("deluser <username> :delete a user");
  else if(conParam.equals("quit"))
   System.out.println("quit  :quit");
  else if(conParam.equals("list"))
   System.out.println("list  :list all user connect to server");
  else if(conParam.equals("listuser"))
   System.out.println("listuser : list all account of this server");
  else if(conParam.equals("help"))
   System.out.println("help :show  this help");
  else
   return false;
  return false;
  
 }//consoleHELP() end
 
 boolean consoleERR()
 {
  System.out.println("bad command!");
  return false;
 }//consoleERR() end
 
 public FtpConsole()
 {
  System.out.println("ftp server started!");
  cin = new BufferedReader(new InputStreamReader(System.in));
 }
 public void run()
 {
  boolean ok = false;
  String input = "";
  while(!ok)
  {
   System.out.print("->");
   try
   {
    input = cin.readLine();
   }
   catch(Exception e)
   {
    e.printStackTrace();
   }
   switch(parseInput(input))
   {
    case 1:
     consoleQUIT();
     break;
    case 8:
     ok = consoleLISTUSER();
     break;
    case 0:
     ok = consoleLIST();
     break;
    case 2:
     ok = consoleADDUSER();
     break;
    case 3:
      ok = consoleDELUSER();
      break;
     case 7:
      ok = consoleHELP();
      break;
     case -1:
      ok = consoleERR();
      break;
   }
  }//while end
 //
 }// run() end
 
 int parseInput(String s)
 {
  String upperCmd;
  int p = 0;
  conCmd = "";
  conParam = "";
  p = s.indexOf(" ");
  if(p == -1)
   conCmd = s;
  else
   conCmd = s.substring(0,p);
  
  if(p >= s.length() || p ==-1)
   conParam = "";
  else
   conParam = s.substring(p+1,s.length());
  upperCmd = conCmd.toUpperCase();
  
  if(upperCmd.equals("LIST"))
   return 0;
  else if(upperCmd.equals("QUIT")||upperCmd.equals("EXIT"))
   return 1;
  else if(upperCmd.equals("ADDUSER"))
   return 2;
  else if(upperCmd.equals("DELUSER"))
   return 3;
  else if(upperCmd.equals("EDITUSER"))
   return 4;
  else if(upperCmd.equals("ADDDIR"))
   return 5;
  else if(upperCmd.equals("REMOVEDIR"))
   return 6;
  else if(upperCmd.equals("HELP") ||upperCmd.equals("?"))
   return 7;
  else if(upperCmd.equals("LISTUSER"))
   return 8;      
  return -1;
 }// parseInput end
}

class FtpState
{
 final static int FS_WAIT_LOGIN = 0;
 final static int FS_WAIT_PASS = 1;
 final static int FS_LOGIN = 2;
 final static int FTYPE_ASCII = 0;
 final static int FTYPE_IMAGE  = 1;
 final static int FMODE_STREAM = 0;
 final static int FMODE_COMPRESSED = 1;
 final static int FSTRU_FILE = 0;
 final static int FSTRU_PAGE = 1;
}

class UserInfo
{
 String user;
 String password;
 String workDir;
}

  ◆ 目录操作,改变或显示远程计算机的当前目录(cd、dir/ls 命令);

  ◆ 连接操作,open命令用于建立同远程计算机的连接;close命令用于关闭连接;

  ◆ 发送操作,put命令用于传送文件到远程计算机;mput 命令用于传送多个文件到远程计算机;

  ◆ 获取操作,get命令用于接收一个文件;mget命令用于接收多个文件。

  ◆ 目录操作,改变或显示远程计算机的当前目录(cd、dir/ls 命令);

  ◆ 连接操作,open命令用于建立同远程计算机的连接;close命令用于关闭连接;

  ◆ 发送操作,put命令用于传送文件到远程计算机;mput 命令用于传送多个文件到远程计算机;

  ◆ 获取操作,get命令用于接收一个文件;mget命令用于接收多个文件。

 

import java.io.*;
import java.net.*;
import java.util.*;

public class FtpServer
{
 private Socket socketClient;
 private int counter;
 public static String initDir;
 public static ArrayList users = new ArrayList();
 public static ArrayList usersInfo = new ArrayList();
 
 public FtpServer()
 {
  FtpConsole fc = new FtpConsole();
  fc.start();
  loadUsersInfo();
  int counter = 1;
  int i = 0;
  try
  {

   //监听21号端口
   ServerSocket s = new ServerSocket(21);
   for(;;)
   {
    //接受客户端请求
    Socket incoming = s.accept();
    BufferedReader in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
       PrintWriter out = new PrintWriter(incoming.getOutputStream(),true);
    out.println("220 Service ready for new user"+counter);

    //创建服务线程
    FtpHandler h = new FtpHandler(incoming,i);
    h.start();
    users.add(h);
    counter++;
    i++;
   }
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
  
 } // FtpServer() end
 
 public void loadUsersInfo()
 {
  String s = getClass().getResource("user.cfg").toString();
  s = s.substring(6,s.length());
  int p1 = 0;
  int p2 = 0;
  if(new File(s).exists())
  {
   try
   {
    BufferedReader fin = new BufferedReader(new InputStreamReader(new FileInputStream(s)));
    String line;
    String field;
    
    
    int i = 0;
    while((line = fin.readLine())!=null)
    {
     UserInfo tempUserInfo = new UserInfo();
     p1 = 0;
     p2 = 0;
     i = 0;
     if(line.startsWith("#"))
      continue;
     while((p2 = line.indexOf("|",p1))!=-1)
     {
      field = line.substring(p1,p2);
      p2 = p2 +1;
      p1 = p2;
      switch(i)
      {
       case 0:
        tempUserInfo.user = field;
        //System.out.println(tempUserInfo.user);
        break;
       case 1:
        tempUserInfo.password = field;
        //System.out.println(tempUserInfo.password);
        break;
       case 2:
        tempUserInfo.workDir = field;
        //System.out.println(tempUserInfo.workDir);
        break;
      }
      i++;
     } //while((p2 = line.indexOf("|",p1))!=-1) end
     usersInfo.add(tempUserInfo);
    }//while((line = fin.readLine())!=null) end
    fin.close();
   }
   catch(Exception e)
   {
    e.printStackTrace();
   }
  }//if(new File(s).exists()) end
 }// loadUsersInfo() end
 
 public static void main(String[] args)
 {
  if(args.length != 0)
  {
   initDir = args[0];
  }
  else
  {
   initDir = "c:/"; 
  }
  FtpServer ftpServer = new FtpServer();
  
 } // main end
  
}

class FtpHandler extends Thread
{
 Socket csocket;
 Socket dsocket;
 int id;
 String cmd = "";
 String param = "";
 String user;
 String remoteHost = " ";
 int remotePort = 0;
 String dir = FtpServer.initDir;
 String rootdir = "c:/";
 int state = 0;
 String reply;
 PrintWriter out;
 int type = 0;
 String requestfile = "";
 boolean isrest = false;
 
 int parseInput(String s)
 {
  int p = 0;
  int i = -1;
  p = s.indexOf(" ");
  if(p == -1)
   cmd = s;
  else
   cmd = s.substring(0,p);
  
  if(p >= s.length() || p ==-1)
   param = "";
  else
   param = s.substring(p+1,s.length());
  cmd = cmd.toUpperCase();
  
  if(cmd.equals("USER"))
    i = 1;
  if(cmd.equals("PASS"))
    i = 2;
  if(cmd.equals("ACCT"))
    i = 3;
    if(cmd.equals("CDUP"))
    i = 4;
  if(cmd.equals("SMNT"))
    i = 5;
  if(cmd.equals("CWD"))
    i = 6;
  if(cmd.equals("QUIT"))
    i = 7;
    if(cmd.equals("REIN"))
    i = 8;
  if(cmd.equals("PORT"))
    i = 9;
  if(cmd.equals("PASV"))
    i = 10;
  if(cmd.equals("TYPE"))
    i = 11;
    if(cmd.equals("STRU"))
    i = 12;
  if(cmd.equals("MODE"))
    i = 13;
  if(cmd.equals("RETR"))
    i = 14;
  if(cmd.equals("STOR"))
    i = 15;
    if(cmd.equals("STOU"))
    i = 16;
  if(cmd.equals("APPE"))
    i = 17;
  if(cmd.equals("ALLO"))
    i = 18;
  if(cmd.equals("REST"))
    i = 19;
    if(cmd.equals("RNFR"))
    i = 20;
  if(cmd.equals("RNTO"))
    i = 21;
  if(cmd.equals("ABOR"))
    i = 22;
  if(cmd.equals("DELE"))
    i = 23;
    if(cmd.equals("RMD"))
    i = 24;
  if(cmd.equals("XMKD"))
    i = 25;    
  if(cmd.equals("MKD"))
    i = 25;
  if(cmd.equals("PWD"))
    i = 26;
  if(cmd.equals("LIST"))
    i = 27;
    if(cmd.equals("NLST"))
    i = 28;
  if(cmd.equals("SITE"))
    i = 29;
  if(cmd.equals("SYST"))
    i = 30;
  if(cmd.equals("HELP"))
    i = 31;
    if(cmd.equals("NOOP"))
    i = 32;
  if(cmd.equals("XPWD"))
    i = 33;
  return i;
 }//parseInput() end
 
 int validatePath(String s)
 {
  File f = new File(s);
  if(f.exists() && !f.isDirectory())
  {
   String s1 = s.toLowerCase();
   String s2 = rootdir.toLowerCase();
   if(s1.startsWith(s2))
    return 1;
   else
    return 0;
  }
  f = new File(addTail(dir)+s);
  if(f.exists() && !f.isDirectory())
  {
   String s1 = (addTail(dir)+s).toLowerCase();
   String s2 = rootdir.toLowerCase();
   if(s1.startsWith(s2))
    return 2;
   else
    return 0;
  }
  return 0;
 }// validatePath() end
 
 boolean checkPASS(String s)
 {
  for(int i = 0; i<FtpServer.usersInfo.size();i++)
  {
   if(((UserInfo)FtpServer.usersInfo.get(i)).user.equals(user) &&
    ((UserInfo)FtpServer.usersInfo.get(i)).password.equals(s))
   {
    rootdir = ((UserInfo)FtpServer.usersInfo.get(i)).workDir;
    dir = ((UserInfo)FtpServer.usersInfo.get(i)).workDir;
    return true;
   }
  }
  return false;
 }// checkPASS() end

 boolean commandUSER()
 {
  if(cmd.equals("USER"))
  {
   reply = "331 User name okay, need password";
   user = param;
     state = FtpState.FS_WAIT_PASS;
   return false;
  }
  else
  {
   reply = "501 Syntax error in parameters or arguments";
   return true;
  }

 }//commandUser() end

 boolean commandPASS()
 {
  if(cmd.equals("PASS"))
  {
   if(checkPASS(param))
   {
    reply = "230 User logged in, proceed";
    state = FtpState.FS_LOGIN;
    System.out.println("Message: user "+user+" Form "+remoteHost+"Login");
    System.out.print("->");
    return false;
   }
   else
   {
    reply = "530 Not logged in";
    return true;
   }
  }
  else
  {
   reply = "501 Syntax error in parameters or arguments";
   return true;
  }

 }//commandPass() end

 void errCMD()
 {
  reply = "500 Syntax error, command unrecognized";
 } 
 
 boolean commandCDUP()
 {
  dir = FtpServer.initDir;
  File f = new File(dir);
  if(f.getParent()!=null &&(!dir.equals(rootdir)))
  {
   dir = f.getParent();
   reply = "200 Command okay";
  }
  else
  {
   reply = "550 Current directory has no parent";
  }
  
  return false;
 }// commandCDUP() end

 boolean commandCWD()
 {
  File f = new File(param);
  String s = "";
  String s1 = "";
  if(dir.endsWith("/"))
   s = dir;
  else
   s = dir + "/";
  File f1 = new File(s+param);
  
  if(f.isDirectory() && f.exists())
  {
   if(param.equals("..") || param.equals("..//"))
   {
    if(dir.compareToIgnoreCase(rootdir)==0)
    {
     reply = "550 The directory does not exists";
     //return false;
    }
    else
    {
     s1 = new File(dir).getParent();
     if(s1!=null)
     {
      dir = s1;
      reply = "250 Requested file action okay, directory change to "+dir;
     }
     else
      reply = "550 The directory does not exists";
    }
   }
   else if(param.equals(".") || param.equals(".//"))
   {
   }
   else
   {
    dir = param;
    reply = "250 Requested file action okay, directory change to "+dir;
   }  
  }
  else if(f1.isDirectory() && f1.exists())
  {
   dir = s+param;
   reply = "250 Requested file action okay, directory change to "+dir;
  }
  else
   reply = "501 Syntax error in parameters or arguments";
  
  return false;
 } // commandCDW() end

 boolean commandQUIT()
 {
  reply = "221 Service closing control connection";
  return true;
 }// commandQuit() end

 boolean commandPORT()
 {
  int p1 = 0;
  int p2 = 0;
  int[] a = new int[6];
  int i = 0;
  try
  {
   while((p2 = param.indexOf(",",p1))!=-1)
   {
     a[i] = Integer.parseInt(param.substring(p1,p2));
     p2 = p2+1;
     p1 = p2;
     i++;
   }
   a[i] = Integer.parseInt(param.substring(p1,param.length()));
  }
  catch(NumberFormatException e)
  {
   reply = "501 Syntax error in parameters or arguments";
   return false;
  }
  
  remoteHost = a[0]+"."+a[1]+"."+a[2]+"."+a[3];
  remotePort = a[4] * 256+a[5];
  reply = "200 Command okay";
  return false;
 }//commandPort() end 
 
 boolean commandLIST()
 {
  try
  {
   dsocket = new Socket(remoteHost,remotePort,InetAddress.getLocalHost(),20);
   PrintWriter dout = new PrintWriter(dsocket.getOutputStream(),true);
   if(param.equals("") || param.equals("LIST"))
   {
    out.println("150 Opening ASCII mode data connection for /bin/ls. ");
    File f = new File(dir);
    String[] dirStructure = f.list();
    String fileType;
    for(int i =0; i<dirStructure.length;i++)
    {
     if(dirStructure[i].indexOf(".")!=-1)
     {
      fileType = "- ";
     }
     else
     {
      fileType = "d ";
     }
     dout.println(fileType+dirStructure[i]);
    }
   }
   dout.close();
   dsocket.close();
   reply = "226 Transfer complete !";
  }
  catch(Exception e)
  {
   e.printStackTrace();
   reply = "451 Requested action aborted: local error in processing";
   return false;
  }
  
  return false;
 }// commandLIST() end

 boolean commandTYPE()
 {
  if(param.equals("a"))
  {
   type = FtpState.FTYPE_ASCII;
   reply = "200 Command okay Change to ASCII mode";
  }
  else if(param.equals("i"))
  {
   type = FtpState.FTYPE_IMAGE;
   reply = "200 Command okay Change to BINARY mode";
  }
  else
   reply = "504 Command not implemented for that parameter";
   
  return false;
 }//commandTYPE() end

 boolean commandRETR()
 {
  requestfile = param;
  File f =  new File(requestfile);
    if(!f.exists())
  {
     f = new File(addTail(dir)+param);
   if(!f.exists())
   {
       reply = "550 File not found";
       return  false;
   }
   requestfile = addTail(dir)+param;
  }
 
    if(isrest)
  {
    
  }
  else
  {
    if(type==FtpState.FTYPE_IMAGE)
   {
    try
    {
     out.println("150 Opening Binary mode data connection for "+ requestfile);
     dsocket = new Socket(remoteHost,remotePort,InetAddress.getLocalHost(),20);
        BufferedInputStream  fin = new BufferedInputStream(new FileInputStream(requestfile));
       PrintStream 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);
     }
      fin.close();
         dout.close();
      dsocket.close();
      reply ="226 Transfer complete !";

    }
    catch(Exception e)
    {
     e.printStackTrace();
     reply = "451 Requested action aborted: local error in processing";
     return false;
    }

   }
   if(type==FtpState.FTYPE_ASCII)
   {
      try
    {
     out.println("150 Opening ASCII mode data connection for "+ requestfile);
     dsocket = new Socket(remoteHost,remotePort,InetAddress.getLocalHost(),20);
        BufferedReader  fin = new BufferedReader(new FileReader(requestfile));
       PrintWriter dout = new PrintWriter(dsocket.getOutputStream(),true);
     String s;
     while((s=fin.readLine())!=null)
     {
         dout.println(s);
     }
      fin.close();
         dout.close();
      dsocket.close();
      reply ="226 Transfer complete !";
    }
    catch(Exception e)
    {
     e.printStackTrace();
     reply = "451 Requested action aborted: local error in processing";
     return false;
    }
   }
  }
    return false;

 }//commandRETR() end

 boolean commandSTOR()
 {
  if(param.equals(""))
  {
   reply = "501 Syntax error in parameters or arguments";
   return false;
  }
  requestfile = addTail(dir)+param;
  if(type == FtpState.FTYPE_IMAGE)
  {
   try
   {
    out.println("150 Opening Binary mode data connection for "+ requestfile);
    dsocket = new Socket(remoteHost,remotePort,InetAddress.getLocalHost(),20);
    BufferedOutputStream fout = new BufferedOutputStream(new FileOutputStream(requestfile));
    BufferedInputStream din = new BufferedInputStream(dsocket.getInputStream());
    byte[] buf = new byte[1024];
    int l = 0;
    while((l = din.read(buf,0,1024))!=-1)
    {
     fout.write(buf,0,l);
    }//while()
    din.close();
    fout.close();
    dsocket.close();
    reply = "226 Transfer complete !";
   }
   catch(Exception e)
   {
    e.printStackTrace();
    reply = "451 Requested action aborted: local error in processing";
    return false;
   }
  }
  if(type == FtpState.FTYPE_ASCII)
  {
   try
   {
    out.println("150 Opening ASCII mode data connection for "+ requestfile);
    dsocket = new Socket(remoteHost,remotePort,InetAddress.getLocalHost(),20);
    PrintWriter fout = new PrintWriter(new FileOutputStream(requestfile));
    BufferedReader din = new BufferedReader(new InputStreamReader(dsocket.getInputStream()));
    String line;
    while((line = din.readLine())!=null)
    {
     fout.println(line);     
    }
    din.close();
    fout.close();
    dsocket.close();
    reply = " 226 Transfer complete !";
   }
   catch(Exception e)
   {
    e.printStackTrace();
    reply = "451 Requested action aborted: local error in processing";
    return false;
   }
  }
  return false;
 }//commandSTOR() end
 
 boolean commandPWD()
 {
  reply = "257 " + dir + " is current directory.";
  return false;
 }//commandPWD() end
 
 boolean commandNOOP()
 {
  reply = "200 OK.";
  return false;
 }//commandNOOP() end
 
 boolean commandABOR()
 {
  try
  {
   dsocket.close();
  }
  catch(Exception e)
  {
   e.printStackTrace();
   reply = "451 Requested action aborted: local error in processing";
   return false;
  }
  reply = "421 Service not available, closing control connection";
  return false;
 }//commandABOR() end
 
 boolean commandDELE()
 {
  int i = validatePath(param);
  if(i == 0)
  {
   reply = "550 Request action not taken";
      return false;
  }
  if(i == 1)
     {
      File f = new File(param);
   f.delete();
     }
  if(i == 2)
  {
   File f= new File(addTail(dir)+param);
   f.delete();
  }
  
  reply = "250 Request file action ok,complete";
  return false;

 }//commandDELE() end

 boolean commandMKD()
 {
  String s1 = param.toLowerCase();
  String s2 = rootdir.toLowerCase();
  if(s1.startsWith(s2))
  {
   File f = new File(param);
   if(f.exists())
   {
    reply = "550 Request action not taken";
    return false;
   }
   else
   {
    f.mkdirs();
    reply = "250 Request file action ok,complete";
   }
  }
  else
  {
   File f = new File(addTail(dir)+param);
   if(f.exists())
   {
    reply = "550 Request action not taken";
    return false;
   }
   else
   {
    f.mkdirs();
    reply = "250 Request file action ok,complete";
   }
  }
  
  return false;
 }//commandMKD() end

 String addTail(String s)
 {
  if(!s.endsWith("/"))
   s = s + "/";
  return s;
 }
 
 public FtpHandler(Socket s,int i)
 {
  csocket = s;
  id = i; 
 }
 
 public void run()
 {
  String str = "";
  int parseResult;
  
  try
  {
   BufferedReader in = new BufferedReader
        (new InputStreamReader(csocket.getInputStream()));
   out = new PrintWriter
        (csocket.getOutputStream(),true);
   state  = FtpState.FS_WAIT_LOGIN;
   boolean finished = false;
   while(!finished)
   {
    str = in.readLine();
    if(str == null) finished = true;
    else
    {
     parseResult = parseInput(str);
     System.out.println("Command:"+cmd+" Parameter:"+param);
     System.out.print("->");
     switch(state)
     {
      case FtpState.FS_WAIT_LOGIN:
        finished = commandUSER();
        break;
      case FtpState.FS_WAIT_PASS:
        finished = commandPASS();
        break;
      case FtpState.FS_LOGIN:
      {
       switch(parseResult)
       {
        case -1:
         errCMD();
         break;
        case 4:
         finished = commandCDUP();
         break;
        case 6:
         finished = commandCWD();
         break;
        case 7:
         finished = commandQUIT();
         break;
        case 9:
         finished = commandPORT();
         break;
        case 27:
         finished = commandLIST();
         break;
        case 11:
         finished = commandTYPE();
         break;
        case 14:
         finished = commandRETR();
         break;
        case 15:
         finished = commandSTOR();
         break;
        case 26:
        case 33:
         finished = commandPWD();
         break;
        case 32:
         finished = commandNOOP();
         break;
        case 22:
         finished = commandABOR();
         break;
        case 23:
         finished = commandDELE();
         break;
        case 25:
         finished = commandMKD();
         break;
        
       }// switch(parseResult) end
      }// case FtpState.FS_LOGIN: end
       break;
      

     }// switch(state) end
    } // else
    out.println(reply);
   } //while
   csocket.close();
  } //try
  catch(Exception e)
  {
   e.printStackTrace();
  }
 }
}

class FtpConsole extends Thread
{
 BufferedReader cin;
 String conCmd;
 String conParam;
 
 int consoleQUIT()
 {
  System.exit(0);
  return 0;
 }//consoleQUIT() end
 
 boolean consoleLISTUSER()
 {
  System.out.println("username /t/t workdirectory");
  for(int i = 0 ; i<FtpServer.usersInfo.size();i++)
  {
   System.out.println(((UserInfo)FtpServer.usersInfo.get(i)).user+" /t/t/t "+((UserInfo)FtpServer.usersInfo.get(i)).workDir);
  }
  return false;
 }//consoleLISTUSER() end
 
 boolean consoleLIST()
 {
  int i = 0;
    for(i=0;i<FtpServer.users.size();i++)
  {
   System.out.println((i+1)+":"+((FtpHandler)(FtpServer.users.get(i))).user + " From " +((FtpHandler)(FtpServer.users.get(i))).csocket.getInetAddress().toString());
  }

       return false;
 }//consoleLIST() end
 
 boolean validateUserName(String s)
 {
  for(int i = 0 ; i<FtpServer.usersInfo.size();i++)
  {
   if(((UserInfo)FtpServer.usersInfo.get(i)).user.equals(s))
    return false; 
  }
  return true;
 }//validateUserName() end

 boolean consoleADDUSER()
 {
  System.out.print("please enter username:");
  try
  {
   cin = new BufferedReader(new InputStreamReader(System.in));
   UserInfo tempUserInfo = new UserInfo();
   String line = cin.readLine();
   if(line != "")
   {
    if(!validateUserName(line))
    {
     System.out.println("user "+line+" already exists!");
     return false;
    }
   }
   else
   {
    System.out.println("username cannot be null!");
    return false;
   }
   tempUserInfo.user = line;
   System.out.print("enter password :");
   line = cin.readLine();
   if(line != "")
    tempUserInfo.password = line;
   else
   {
    System.out.println("password cannot be null!");
    return false;
   }
   System.out.print("enter the initial directory: ");
   line = cin.readLine();
   if(line != "")
   {
    File f = new File(line);
    if(!f.exists())
     f.mkdirs();
    tempUserInfo.workDir = line;
   }
   else
   {
    System.out.println("the directory cannot be null!");
    return false;
   }
   FtpServer.usersInfo.add(tempUserInfo);
   saveUserInfo();
  }
  catch(Exception e)
  {
   e.printStackTrace();
   return false;
  }
  return false;
 }//consoleADDUSER() end
 
 void saveUserInfo()
 {
  String s = "";
  try
  {
   BufferedWriter fout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("user.cfg")));
   for(int i = 0; i < FtpServer.usersInfo.size();i++)
   {
    s = ((UserInfo)FtpServer.usersInfo.get(i)).user+"|"+((UserInfo)FtpServer.usersInfo.get(i)).password+"|"+((UserInfo)FtpServer.usersInfo.get(i)).workDir+"|";
    fout.write(s);
    fout.newLine();
   }
   fout.close();
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
 }//saveUserInfo() end
 
 boolean consoleDELUSER()
 {
  String s = "";
  //System.out.println(conParam);
  if(conParam.equals(""))
  {
   System.out.println("usage:deluser username");
   return false;
  }
  for(int i=0;i<FtpServer.usersInfo.size();i++)
  {
   s = ((UserInfo)FtpServer.usersInfo.get(i)).user;
   if(s.equals(conParam))
   {
    System.out.println("User "+conParam+" deleted");
                FtpServer.usersInfo.remove(i);
    saveUserInfo();
    return false;
   }
  }
  System.out.println("User "+conParam+" not exists");     
  return false;

 }//consoleDELUSER() end
 
 boolean consoleHELP()
 {
  if(conParam.equals(""))
  {
   System.out.println("adduser :add new user");
   System.out.println("deluser <username> :delete a user");
   System.out.println("quit  :quit");
   System.out.println("list  :list all user connect to server");
   System.out.println("listuser : list all account of this server");
   System.out.println("help :show  this help");
  }
  else if(conParam.equals("adduser"))
   System.out.println("adduser :add new user");
  else if(conParam.equals("deluser"))
   System.out.println("deluser <username> :delete a user");
  else if(conParam.equals("quit"))
   System.out.println("quit  :quit");
  else if(conParam.equals("list"))
   System.out.println("list  :list all user connect to server");
  else if(conParam.equals("listuser"))
   System.out.println("listuser : list all account of this server");
  else if(conParam.equals("help"))
   System.out.println("help :show  this help");
  else
   return false;
  return false;
  
 }//consoleHELP() end
 
 boolean consoleERR()
 {
  System.out.println("bad command!");
  return false;
 }//consoleERR() end
 
 public FtpConsole()
 {
  System.out.println("ftp server started!");
  cin = new BufferedReader(new InputStreamReader(System.in));
 }
 public void run()
 {
  boolean ok = false;
  String input = "";
  while(!ok)
  {
   System.out.print("->");
   try
   {
    input = cin.readLine();
   }
   catch(Exception e)
   {
    e.printStackTrace();
   }
   switch(parseInput(input))
   {
    case 1:
     consoleQUIT();
     break;
    case 8:
     ok = consoleLISTUSER();
     break;
    case 0:
     ok = consoleLIST();
     break;
    case 2:
     ok = consoleADDUSER();
     break;
    case 3:
      ok = consoleDELUSER();
      break;
     case 7:
      ok = consoleHELP();
      break;
     case -1:
      ok = consoleERR();
      break;
   }
  }//while end
 //
 }// run() end
 
 int parseInput(String s)
 {
  String upperCmd;
  int p = 0;
  conCmd = "";
  conParam = "";
  p = s.indexOf(" ");
  if(p == -1)
   conCmd = s;
  else
   conCmd = s.substring(0,p);
  
  if(p >= s.length() || p ==-1)
   conParam = "";
  else
   conParam = s.substring(p+1,s.length());
  upperCmd = conCmd.toUpperCase();
  
  if(upperCmd.equals("LIST"))
   return 0;
  else if(upperCmd.equals("QUIT")||upperCmd.equals("EXIT"))
   return 1;
  else if(upperCmd.equals("ADDUSER"))
   return 2;
  else if(upperCmd.equals("DELUSER"))
   return 3;
  else if(upperCmd.equals("EDITUSER"))
   return 4;
  else if(upperCmd.equals("ADDDIR"))
   return 5;
  else if(upperCmd.equals("REMOVEDIR"))
   return 6;
  else if(upperCmd.equals("HELP") ||upperCmd.equals("?"))
   return 7;
  else if(upperCmd.equals("LISTUSER"))
   return 8;      
  return -1;
 }// parseInput end
}

class FtpState
{
 final static int FS_WAIT_LOGIN = 0;
 final static int FS_WAIT_PASS = 1;
 final static int FS_LOGIN = 2;
 final static int FTYPE_ASCII = 0;
 final static int FTYPE_IMAGE  = 1;
 final static int FMODE_STREAM = 0;
 final static int FMODE_COMPRESSED = 1;
 final static int FSTRU_FILE = 0;
 final static int FSTRU_PAGE = 1;
}

class UserInfo
{
 String user;
 String password;
 String workDir;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值