來源:automationer 發(fā)布時(shí)間:2018-11-21 15:24:54 閱讀量:1001
1.主程序
package server;
import java.net.ServerSocket;
import java.net.Socket;
public class FtpServer extends Thread{
public static final int FTP_PORT=21;//服務(wù)器默認(rèn)端口21
ServerSocket ftpsocket=null;//服務(wù)器套接字
public static void main(String[] args){
FtpConnection.root="C:\\ftp\\";
System.out.println("[info] ftp server root: "+FtpConnection.root );
new FtpServer().start();//創(chuàng)建FtpServer主線程對(duì)象,并運(yùn)行
}
public void run(){
Socket client=null;
try{
ftpsocket=new ServerSocket(FTP_PORT);
System.out.println("[info] listening port: "+FTP_PORT);
for(;;){
client=ftpsocket.accept();//監(jiān)控端口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;//當(dāng)前服務(wù)器的根目錄
private String currentDir="/";//當(dāng)前服務(wù)器上的工作目錄
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();//獲取客戶機(jī)主機(jī)IP地址
}
//run()方法運(yùn)行線程,創(chuàng)建服務(wù)器與客戶端通信的字符流
//獲得用戶命令,處理命令,當(dāng)收到QUIT時(shí),關(guān)閉連接,結(jié)束Ftp會(huì)話
public void run(){
String command;
System.out.println(clientIP+" connected.");
try {
socket.setSoTimeout(10000);//Ftp超時(shí)設(shè)定
//字符輸入流,接收客戶端字符信息流
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//字符輸出流,發(fā)送至客戶端字符信息流
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.");
}
}
//服務(wù)器發(fā)送響應(yīng)信息
private void response(String s) throws Exception {
// TODO Auto-generated method stub
System.out.println("[服務(wù)器]應(yīng)答:"+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;
}
//打印當(dāng)前目錄
if(s.equals("PWD ")){
response("257 \""+this.currentDir+"\""+"is current directory");
}
//主動(dòng)模式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.");
}
}
//被動(dòng)模式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();//被動(dòng)模式
else
dataSocket_retr=new Socket(this.host,this.port);//主動(dòng)模式
RandomAccessFile inFile=new RandomAccessFile(root+"/"+str, "r");//隨機(jī)訪問文件
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){//通過隨機(jī)訪問文件,在服務(wù)器上讀文件
outSocket.write(byteBuffer, 0, amount_retr);//通過輸出流,發(fā)送到客戶端
}
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");//隨機(jī)訪問文件
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]);//名稱發(fā)送到客戶端
}
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");
}
}
---------------------
在線
客服
服務(wù)時(shí)間:周一至周日 08:30-18:00
選擇下列產(chǎn)品馬上在線溝通:
客服
熱線
7*24小時(shí)客服服務(wù)熱線
關(guān)注
微信
關(guān)注官方微信