FTP服务器端的实现

来源:automationer 发布时间:2018-11-21 15:24:54 阅读量:815

1.主程序


package server;

 

import java.net.ServerSocket;

import java.net.Socket;

 

public class FtpServer extends Thread{

public static final int FTP_PORT=21;//服务器默认端口21

ServerSocket ftpsocket=null;//服务器套接字

public static void main(String[] args){

FtpConnection.root="C:\\ftp\\";

System.out.println("[info] ftp server root: "+FtpConnection.root );

new FtpServer().start();//创建FtpServer主线程对象,并运行

}

public void run(){

Socket client=null;

try{

ftpsocket=new ServerSocket(FTP_PORT);

System.out.println("[info] listening port: "+FTP_PORT);

for(;;){

client=ftpsocket.accept();//监控端口FTP_PORT=21,返回客户端套接字

new FtpConnection(client).start();

}

}catch(Exception e){

e.printStackTrace();

}

}

}


2.命令处理程序


package server;

 

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.io.RandomAccessFile;

import java.net.InetAddress;

import java.net.ServerSocket;

import java.net.Socket;

 

public class FtpConnection {

public static String root=null;//当前服务器的根目录

private String currentDir="/";//当前服务器上的工作目录

private Socket socket;//套接字

private BufferedReader reader=null;//字符输入流

private BufferedWriter writer=null;//字符输出流

private String clientIP=null;//客户端IP地址

private String host=null;//客户端端口

private int port=-1;//客户端端口

String user;

public FtpConnection(Socket socket){//获得客户端套接字信息

this.socket=socket;//客户端通信套接字

this.clientIP=socket.getInetAddress().getHostAddress();//获取客户机主机IP地址

}

//run()方法运行线程,创建服务器与客户端通信的字符流

//获得用户命令,处理命令,当收到QUIT时,关闭连接,结束Ftp会话

public void run(){

String command;

System.out.println(clientIP+" connected.");

try {

socket.setSoTimeout(10000);//Ftp超时设定

//字符输入流,接收客户端字符信息流

reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));

//字符输出流,发送至客户端字符信息流

writer=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

response("220-欢迎消息...");

for(;;){

command=reader.readLine();//获取客户端命令

if(command==null)

break;

System.out.println("command from "+clientIP+":"+command);

parseCommand(command);

if(command.equals("QUIT"))

break;

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally{

try{

if(reader!=null)

reader.close();

}catch(Exception e){

System.out.println("[info] reader==null");

}

try{

if(writer!=null)

writer.close();

}catch(Exception e){

System.out.println("[info] writer==null");

}

try{

if(this.socket!=null)

socket.close();

}catch(Exception e){

System.out.println("[info] this.socket==null");

}

System.out.println(clientIP+"disconnected.");

}

}

//服务器发送响应信息

private void response(String s) throws Exception {

// TODO Auto-generated method stub

System.out.println("[服务器]应答:"+s);

writer.write(s);

writer.newLine();

writer.flush();

}

//获取命令行中,命令后面附带的信息

private String getParam(String st,String cmd){

String string=st.substring(cmd.length(), st.length());

return string.trim();

}

//用户命令处理

private void parseCommand(String s) throws Exception {

// TODO Auto-generated method stub

if(s==null||s.equals(""))

return;

if(s.startsWith("USER")){

user=s.substring(4);

user=user.trim();

response("311 need passwrd");

return;

}

if(s.equals("PASS")){

response("230 welcome to my ftp! User:"+user);

return;

}

if(s.equals("QUIT")){

response("221 good bye!");

return;

}

if(s.equals("TYPE A")){

response("200 TYPE set to A.");

return;

}

if(s.equals("TYPE I")){

response("200 TYPE set to I.");

return;

}

if(s.equals("NOOP")){

response("200 NOOP OK.");

return;

}

//改变工作目录到指定的目录,注意没有检查目录是否有效

if(s.startsWith("CWD")){

this.currentDir=getParam(s, "CWD ");

response("250 CWD command successful.");

return;

}

//打印当前目录

if(s.equals("PWD ")){

response("257 \""+this.currentDir+"\""+"is current directory");

}

//主动模式PORT(PORT)命令

if(s.startsWith("PORT ")){

String[] params=getParam(s,"PORT ").split(",");

if(params.length<=4 || params.length>=7)

response("500 command param error.");

else{

this.host=params[0]"."params[1]"."params[2]"."params[3];

String port1=null;

String port2=null;

if(params.length==6){

port1=params[4];

port2=params[5];

}

else{

port1="0";

port2=params[4];

}

this.port=Integer.parseInt(port1)*256+Integer.parseInt(port2);

response("200 command successful.");

}

}

//被动模式PASV(PASSIVE)命令

ServerSocket pasvSocket=new ServerSocket();

Socket dataSocket;

if(s.equals("PASV ")){

if(pasvSocket!=null){

pasvSocket.close();

}

try {

pasvSocket=new ServerSocket(0);

int pPort=pasvSocket.getLocalPort();

if(pPort<1024)

pPort=1025;

pasvSocket.setSoTimeout(10000);

response("227 entering passive mode ("+InetAddress.getLocalHost().getHostAddress().replace(',', '.')+","+pPort+")");

if(pasvSocket!=null)

dataSocket=pasvSocket.accept();

} catch (Exception e) {

if(pasvSocket!=null){

pasvSocket.close();

pasvSocket=null;

}

}

return;

}

//文件下载命令RETR(RETEIEVE)

if(str.startsWith("RETR ")){

Socket dataSocket_retr;

str=getParam(str, "RETR");

str=str.trim();

if(pasvSocket!=null)

dataSocket_retr=pasvSocket.accept();//被动模式

else

dataSocket_retr=new Socket(this.host,this.port);//主动模式

RandomAccessFile inFile=new RandomAccessFile(root+"/"+str, "r");//随机访问文件

OutputStream outSocket=new dataSocket_retr.getOutputStream();//输出流

byte byteBuffer[]=new byte[1024];

int amount_retr;

response("150 opening ascii mode data connection.");

try{

while((amount_retr=inFile.read(byteBuffer)) != -1){//通过随机访问文件,在服务器上读文件

outSocket.write(byteBuffer, 0, amount_retr);//通过输出流,发送到客户端

}

outSocket.close();

inFile.close();

dataSocket_retr.close();

response("226 transfer complete");

}catch(IOException e){

response("550 ERROR:File not found or access denied.");

}

return;

}

//文件上传命令STOR(STORE)

if(str.startsWith("STOR")){

Socket dataSocket_stor;

str=getParam(str, "STOR");

str=str.trim();

if(pasvSocket!=null)

dataSocket_stor = pasvSocket.accept();

else

dataSocket_stor=new Socket(this.host,this.port);

RandomAccessFile inFile=new RandomAccessFile(root+"/"+str, "rw");//随机访问文件

InputStream inSocket=dataSocket_stor.getInputStream();

byte byteBuffer[]=new byte[1024];

int amount_stor;

response("150 binary data connection");

try{

while((amount_stor=inSocket.read(byteBuffer))!=-1){

inFile.write(byteBuffer,0,amount_stor);

}

inSocket.close();

response("226 tranfer complete");

inFile.close();

dataSocket_stor.close();

}catch(IOException e){

response("550 error:file not found or access denied");

}

return;

}

//文件和目录列表LIST命令

if(str.startsWith("LIST")){

Socket dataSocket_list;

if(pasvSocket!=null)

dataSocket_list=pasvSocket.accept();

else

dataSocket_list=new Socket(this.host,this.port);

PrintWriter out=new PrintWriter(dataSocket_list.getOutputStream(), true);

File file=new File(root);

String[] dirStructrue=new String[10];

String strType="";

response("150 opening ascii mode data connection.");

try{

dirStructrue=file.list();

for(int i=0;i<dirStructrue.length;i++){

if(dirStructrue[i].indexOf(".")==-1){

strType="d ";

}

else{

strType="- ";

}

out.println(strType+dirStructrue[i]);//名称发送到客户端

}

out.close();

dataSocket_list.close();

response("226 transfer complete");

}catch(IOException e){

out.close();

dataSocket_list.close();

response(e.getMessage());

}

return;

}

response("500 invalid command");

}

}


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



标签: 服务器搭建
分享:
评论:
你还没有登录,请先