// ftp 程序Ftp.java
// 此程序的功能是建立与ftp服务器的连接并实现文件传输
// 使用方法:java Ftp 服务器地址
//启动示例:java Ftp kiku.fuis.fukui-u.ac.jp
// 导入库
import java.net.*;
import java.io.*;
// Ftp类
public class FTP {
 Socket ctrlSocket;//控制用Socket
 public PrintWriter ctrlOutput;//控制输出用的流
 public BufferedReader ctrlInput;// 控制输入用的流
 final int CTRLPORT = 21 ;// ftp 的控制用端口
 // openConnection方法
 //由地址和端口号构造Socket,形成控制用的流
 public void openConnection(String host)
  throws IOException,UnknownHostException
 {
  ctrlSocket = new Socket(host, CTRLPORT);
  ctrlOutput = new PrintWriter(ctrlSocket.getOutputStream());
  ctrlInput
   = new BufferedReader(new InputStreamReader
        (ctrlSocket.getInputStream()));
 }
 // closeConnection方法
 //关闭控制用的Socket
 public void closeConnection()
  throws IOException
 {
  ctrlSocket.close() ;
 }
 // showMenu方法
 // 输出ftp的命令菜单
 public void showMenu()
 {
  System.out.println(">Command?") ;
  System.out.print("2 ls") ;
  System.out.print(" 3 cd") ;
  System.out.print(" 4 get") ;
  System.out.print(" 5 put") ;
  System.out.println(" 6 quit") ;
 }
 // getCommand方法
 // 读取用户指定的命令序号
 public String getCommand()
 {
  String buf = "" ;
  BufferedReader lineread
   = new BufferedReader(new InputStreamReader(System.in)) ;
  while(buf.length() != 1){// 循环接收一个字符的输入
   try{
    buf = lineread.readLine() ;
   }catch(Exception e)
   {
    e.printStackTrace();
    System.exit(1);
   }
  }
  return (buf) ;
 }
 // doLogin方法
 // 登录到ftp服务器
 public void doLogin()
 {
  String loginName = "" ;
  String password = "" ;
  BufferedReader lineread
   = new BufferedReader(new InputStreamReader(System.in)) ;
  try{
   System.out.println("请输入用户名") ;
   loginName = lineread.readLine() ;
   // 利用USER命令登录
   ctrlOutput.println("USER " + loginName) ;
   ctrlOutput.flush() ;
   // 利用PASS命令输入口令
   System.out.println("请输入口令") ;
   password = lineread.readLine() ;
   ctrlOutput.println("PASS " + password) ;
   ctrlOutput.flush() ;
  }catch(Exception e)
  {
   e.printStackTrace();
   System.exit(1);
  }
 }
 // doQuit方法
 // 从ftp服务器注销
 public void doQuit()
 {
  try{
   ctrlOutput.println("QUIT ") ;// 发送QUIT命令
   ctrlOutput.flush() ;
  }catch(Exception e)
  {
   e.printStackTrace();
   System.exit(1);
  }
 }
 // doCd方法
 // 切换目录
 public void doCd()
 {
  String dirName = "" ;
  BufferedReader lineread
   = new BufferedReader(new InputStreamReader(System.in)) ;
  try{
   System.out.println("请输入目录名") ;
   dirName = lineread.readLine() ;
   ctrlOutput.println("CWD " + dirName) ;// CWD命令
   ctrlOutput.flush() ;
  }catch(Exception e)
  {
   e.printStackTrace();
   System.exit(1);
  }
 }
 // doLs方法
 // 取得目录信息
 public void doLs()
 {
  try{
   int n ;
   byte[] buff = new byte[1024] ;
   // 建立数据连接
   Socket dataSocket = dataConnection("LIST") ;
   // 准备读取数据用的流
   BufferedInputStream dataInput
    = new BufferedInputStream(dataSocket.getInputStream()) ;
   // 读取目录信息
   while((n = dataInput.read(buff)) > 0){
    System.out.write(buff,0,n) ;
   }
   dataSocket.close() ;
  }catch(Exception e)
  {
   e.printStackTrace();
   System.exit(1);
  }
 }
 // dataConnection方法
 // 构造与服务器交换数据用的Socket
 // 再用PORT命令将端口通知服务器
 public Socket dataConnection(String ctrlcmd)
 {
  String cmd = "PORT " ; //PORT存放用PORT命令传递数据的变量
  int i ;
  Socket dataSocket = null ;// 传送数据用Socket
  try{
   // 得到自己的地址
   byte[] address = InetAddress.getLocalHost().getAddress() ;
   // 用适当的端口号构造服务器
   ServerSocket serverDataSocket = new ServerSocket(0,1) ;
   // 准备传送PORT命令用的数据
   for(i = 0; i < 4; ++i)
    cmd = cmd + (address[i] & 0xff) + "," ;
    cmd = cmd + (((serverDataSocket.getLocalPort()) / 256) & 0xff)
       + ","+ (serverDataSocket.getLocalPort() & 0xff) ;
   // 利用控制用的流传送PORT命令
   ctrlOutput.println(cmd) ;
   ctrlOutput.flush() ;
   // 向服务器发送处理对象命令(LIST,RETR,及STOR)
   ctrlOutput.println(ctrlcmd) ;
   ctrlOutput.flush() ;
   // 接受与服务器的连接
   dataSocket = serverDataSocket.accept() ;
   serverDataSocket.close() ;
  }catch(Exception e)
  {
   e.printStackTrace();
   System.exit(1);
  }
  return dataSocket ;
 }
 
 // doGet方法
 // 取得服务器上的文件
 public void doGet()
 {
  String fileName = "" ;
  BufferedReader lineread
   = new BufferedReader(new InputStreamReader(System.in)) ;
  try{
   int n ;
   byte[] buff = new byte[1024] ;
   // 指定服务器上的文件名
   System.out.println("选择文件:") ;
   fileName = lineread.readLine() ;
   // 在客户端上准备接收用的文件
   FileOutputStream outfile = new FileOutputStream(fileName) ;
   // 构造传输文件用的数据流
   Socket dataSocket = dataConnection("RETR " + fileName) ;
   BufferedInputStream dataInput
    = new BufferedInputStream(dataSocket.getInputStream()) ;
   // 接收来自服务器的数据,写入本地文件
   while((n = dataInput.read(buff)) > 0){
    outfile.write(buff,0,n) ;
   }
   dataSocket.close() ;
   outfile.close() ;
  }catch(Exception e)
  {
   e.printStackTrace();
   System.exit(1);
  }
 }
 // doPut方法
 // 向服务器发送文件
 public void doPut()
 {
  String fileName = "" ;
  BufferedReader lineread
   = new BufferedReader(new InputStreamReader(System.in)) ;
  try{
   int n ;
   byte[] buff = new byte[1024] ;
   FileInputStream sendfile = null ;
   // 指定文件名
   System.out.println("请输入文件名") ;
   fileName = lineread.readLine() ;
   // 准备读出客户端上的文件
   try{
    sendfile = new FileInputStream(fileName) ;
   }catch(Exception e){
    System.out.println("文件不存在") ;
    return ;
   }
   // 准备发送数据的流
   Socket dataSocket = dataConnection("STOR " + fileName) ;
   OutputStream outstr = dataSocket.getOutputStream() ;
   // 读出文件,并利用网络发送给服务器
   while((n = sendfile.read(buff)) > 0){
    outstr.write(buff,0,n) ;
   }
   dataSocket.close() ;
   sendfile.close() ;
  }catch(Exception e)
  {
   e.printStackTrace();
   System.exit(1);
  }
 }
 // execCommand方法
 // 执行与各命令相应的处理
 public boolean execCommand(String command)
 {
  boolean cont = true ;
  switch(Integer.parseInt(command)){
  case 2 : // 显示服务器目录信息
   doLs() ;
   break ;
  case 3 : // 切换服务器的工作目录
   doCd() ;
   break ;
  case 4 : // 取得服务器上的文件
   doGet() ;
   break ;
  case 5 : // 向服务器发送文件
   doPut() ;
   break ;
  case 6 : // 处理结束
   doQuit() ;
   cont = false ;
   break ;
  default : //其他输入
   System.out.println("请选择一个序号") ;
  }
  return(cont) ;
 }
 // main_proc方法
 // 输出ftp的命令菜单,调用各种处理方法
 public void main_proc()
  throws IOException
 {
  boolean cont = true ;
  try {
   // 进行登录
   doLogin() ;
   while(cont){
   // 输出菜单
   showMenu() ;
   // 接收并执行命令
   cont = execCommand(getCommand()) ;
   }
  }
  catch(Exception e){
   System.err.print(e);
   System.exit(1);
  }
 }
 // getMsgs方法
 // 启动从控制流收信的线程
 public void getMsgs(){
  try {
   CtrlListen listener = new CtrlListen(ctrlInput) ;
   Thread listenerthread = new Thread(listener) ;
   listenerthread.start() ;
  }catch(Exception e){
   e.printStackTrace() ;
   System.exit(1) ;
  }
 }
 // main方法
 // 建立TCP连接,开始处理
 /**
 * @param arg
 */
public static void main(String[] arg){
  try {
  FTP f = null;  if(arg.length <1){
  System.out.println("用法: java Ftp <host name>") ;
  return ;
  }   f = new FTP();
   f.openConnection(arg[0]); // 控制连接建立
   f.getMsgs() ; // 启动接收线程
   f.main_proc(); // ftp 处理
   f.closeConnection() ; // 关闭连接
   System.exit(0) ; // 结束程序
  }catch(Exception e){
   e.printStackTrace();
   System.exit(1);
  }
 }
}
// CtrlListen 类
class CtrlListen implements Runnable{
 BufferedReader ctrlInput = null ;
 // 构造器 指定读取地址
 public CtrlListen(BufferedReader in){
  ctrlInput = in ;
 }
 public void run(){
  while(true){
   try{ // 按行读入并输出到标准输出上
    System.out.println(ctrlInput.readLine()) ;
   } catch (Exception e){
    System.exit(1) ;
   }
  }
 }
}
每次运行之后都是出现“用法: java Ftp <host name>”,没有往下运行了,希望各位高手能帮忙看看,小弟初学者,程序是从网上找的,想弄弄明白!!谢谢了先

解决方案 »

  1.   

    if(arg.length <1){
      System.out.println("用法: java Ftp <host name>") ;你要指定命令行参数
      

  2.   

    具体如何实现啊??我刚学JAVA,实在不好意思啊!
      

  3.   

    不知道你用的是什么IDE,要是用eclipse的话,Run -> Open Run Dialog -> Arguments -> Program argument
    另外你也可以直接运行命令java Ftp <host name>,  这里的host name就是你的ftp主机名
      

  4.   

    java.net.ConnectException: Connection refused: connect
     at java.net.PlainSocketImpl.socketConnect(Native Method)
     at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
     at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
     at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
     at java.net.Socket.connect(Socket.java:518)
     at java.net.Socket.connect(Socket.java:468)
     at java.net.Socket.<init>(Socket.java:365)
     at java.net.Socket.<init>(Socket.java:179)
     at FTP.openConnection(FTP.java:19)
     at FTP.main(FTP.java:317)
    出现这样的错误!!怎么解决啊!?