java与ftp连接_建立与ftp服务器的连接——完成版(java)

  • Post author:
  • Post category:java


// 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.print(” 6 ascii”) ;

System.out.print(” 7 binary”) ;

System.out.println(” 9 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 ;

}

// doAscii方法

// 设置文本传输模式

public void doAscii()

{

try{

ctrlOutput.println(“TYPE A”) ;// A模式

ctrlOutput.flush() ;

}catch(Exception e)

{

e.printStackTrace();

System.exit(1);

}

}

// doBinary方法

// 设置二进制传输模式

public void doBinary()

{

try{

ctrlOutput.println(“TYPE I”) ;// I模式

ctrlOutput.flush() ;

}catch(Exception e)

{

e.printStackTrace();

System.exit(1);

}

}

// 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 : // 文件传输模式

doAscii() ;

break ;

case 7 : // 二进制传输模式

doBinary() ;

break ;

case 9 : // 处理结束

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连接,开始处理

public static void main(String[] arg){

try {

Ftp f = null;

if(arg.length < 1){

System.out.println(“usage: java Ftp “) ;

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



版权声明:本文为weixin_34626572原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。