⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 accoutserverforremote.java

📁 用java写的ftp服务器程序
💻 JAVA
字号:
/**
 * 
 */
package org.apache.ftpserver;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.Random;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ftpserver.ftplet.Component;
import org.apache.ftpserver.ftplet.Configuration;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.User;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.interfaces.IFtpConfig;
import org.apache.ftpserver.usermanager.BaseUser;
import org.apache.ftpserver.util.SocketChannelHelper;
import org.apache.ftpserver.util.XmlUtils;
import org.jdom.Document;
import org.jdom.Element;

/**
 * 2006-7-7 10:52:37
 * 
 * @author xudz 为远程机器建立和删除帐号的线程, 此操作为非标准FTP操作
 */
public class AccoutServerForRemote extends Thread  {

	private IFtpConfig ftpConfig;

	private int port = 21210;

	private Log m_log;

	ServerSocketChannel channelServer;

	private boolean isClosed = false;

	private final static Random PASS_GEN = new Random(System
			.currentTimeMillis());

	/**
	 * 
	 */
	public AccoutServerForRemote(IFtpConfig config) {
		super();
		this.ftpConfig = config;
	}

	public void run() {
		this.m_log.info("accout thread started!");
		try {
			channelServer = ServerSocketChannel.open();
			ServerSocket socketServer = channelServer.socket();
			SocketAddress address = new InetSocketAddress(port);
			socketServer.bind(address);
		} catch (IOException e) {
			m_log.error(e.getMessage());
			return;
		}
		while (true) {
			if (isClosed == true)
				return;
			SocketChannel sock = null;
			try {
				sock = channelServer.accept();
			} catch (IOException e) {
				m_log.error(e.getMessage());
			}
			if (sock != null)
				processRequest(sock);
		}
	}

	private void processRequest(SocketChannel sock) {
		Document rcvDoc = null;
		try {
			rcvDoc = this.rcvReqDoc(sock);
		} catch (Exception e) {
			m_log.error(e.getMessage());
			this.closeSockChannel(sock);
			return;
		}

		String busi = rcvDoc.getRootElement().getChildText("busi");
		String action = rcvDoc.getRootElement().getChildText("action");
		Document sendDoc = null;

		try {
			XmlUtils.printDocument(rcvDoc,System.out);
			if ("ftp.addition".equals(busi) && "add.account".equals(action)) {
				sendDoc = this.dealAddAccountReq(rcvDoc);
			} else if ("ftp.addition".equals(busi)
					&& "delete.account".equals(action)) {
				sendDoc = this.dealDeleteAccountReq(rcvDoc);

			} else {
				m_log.error("busi or action do not recognize!");
				this.closeSockChannel(sock);
				return;
			}
		} catch (Exception e2) {
			e2.printStackTrace();
			this.m_log.error(e2.getMessage());
			sendDoc = this.createErrorDoc(e2.getMessage());
		}

		this.sendBackDoc(sock, sendDoc);
	}

	private Document dealAddAccountReq(Document rcvDoc) throws FtpException {
		UserManager userMan = this.ftpConfig.getUserManager();
		Element root = rcvDoc.getRootElement();
		Element parEle = root.getChild("parentAccount");
		String parName = parEle.getChildText("name");
		String parPass = parEle.getChildText("pass");

		boolean isAuth = false;
		if (!"anonymous".equals(parName) && userMan.doesExist(parName))
			isAuth = userMan.authenticate(parName, parPass);
		if (isAuth == false)
			return this.createErrorDoc("authenticate error!");
		Element newAccEle = root.getChild("newAccount");
		String newAccName = newAccEle.getChildText("name");
		String newAccDir = newAccEle.getChildText("rootDirName");
		if (userMan.doesExist(newAccName))
			return this
					.createErrorDoc("Already exist login name:" + newAccName);
		User parUser = userMan.getUserByName(parName);
		File uploadFile = new File(parUser.getHomeDirectory(), "upload");
		File newUserHomeDir = new File(uploadFile, newAccDir);
		if (!newUserHomeDir.exists())
			newUserHomeDir.mkdirs();
		String password = this.generatePassword();
		BaseUser newUser = new BaseUser();
		newUser.setName(newAccName);
		newUser.setHomeDirectory(newUserHomeDir.getAbsolutePath());
		newUser.setPassword(password);
		newUser.setEnabled(parUser.getEnabled());
		newUser.setMaxDownloadRate(parUser.getMaxDownloadRate());
		newUser.setMaxIdleTime(parUser.getMaxIdleTime());
		newUser.setMaxUploadRate(parUser.getMaxUploadRate());
		newUser.setWritePermission(parUser.getWritePermission());

		userMan.save(newUser);

		Document rtnDoc = this.createSuccDoc("add new Account successfully!");
		Element rtnAccountEle = new Element("account");
		rtnAccountEle.getChildren()
				.add(new Element("name").setText(newAccName));
		rtnAccountEle.getChildren().add(new Element("pass").setText(password));
		rtnDoc.getRootElement().getChildren().add(rtnAccountEle);

		StringBuffer sb = new StringBuffer("new Accout Created,name:");
		sb.append(newAccName);
		sb.append(",pass:");
		sb.append(password);
		m_log.info(sb.toString());
		
		return rtnDoc;
	}
	

	private Document dealDeleteAccountReq(Document rcvDoc) throws FtpException{
		UserManager userMan = this.ftpConfig.getUserManager();
		Element root = rcvDoc.getRootElement();
		Element parEle = root.getChild("parentAccount");
		String parName = parEle.getChildText("name");
		String parPass = parEle.getChildText("pass");

		boolean isAuth = false;
		if (!"anonymous".equals(parName) && userMan.doesExist(parName))
			isAuth = userMan.authenticate(parName, parPass);
		if (isAuth == false)
			return this.createErrorDoc("authenticate error!");
		Element discardEle = root.getChild("discardAccount");
		String discardAccName = discardEle.getChildText("name");

		if (!userMan.doesExist(discardAccName))
			return this
					.createErrorDoc("no login name exist:" + discardAccName);

		userMan.delete(discardAccName);

		Document rtnDoc = this.createSuccDoc("delete Account successfully!");
		Element rtnAccountEle = new Element("account");
		rtnAccountEle.getChildren()
				.add(new Element("name").setText(discardAccName));
		rtnDoc.getRootElement().getChildren().add(rtnAccountEle);

		m_log.info("succeed to delete accout,name :" + discardAccName);
		return rtnDoc;

	}

	private void sendBackDoc(SocketChannel sock, Document doc) {
		SocketChannelHelper sockHelper = SocketChannelHelper.getInstance();
		ByteBuffer buff = null;
		try {
			buff = this.getSendBuffer(doc);
			sockHelper.sendData(sock, buff, 6000);
		} catch (Exception e) {
			e.printStackTrace();
			this.m_log.error(e.getMessage());
		} finally {
			this.closeSockChannel(sock);
		}
	}

	private ByteBuffer getSendBuffer(Document doc) throws IOException {
		byte[] xmlByte = null;
		try {
			xmlByte = XmlUtils.transferDocToByte(doc);
		} catch (IOException e) {
			throw new IOException("xml转换成Byte失败");
		}

		byte[] head = getHeadByte(xmlByte.length, 6);
		String headStr = "rt" + new String(head);
		byte[] headByte = headStr.getBytes();

		ByteBuffer buff = ByteBuffer.allocate(xmlByte.length + headByte.length);
		buff.clear();
		buff.put(headByte);
		buff.put(xmlByte);
		buff.flip();

		return buff;
	}

	/**
	 * 根据传递的参数生成固定包头的byte
	 * 
	 * @param dataLen
	 *            byte数组的长度
	 * @param size
	 *            固定包头长度
	 * @return 以十六进制表示的dataLen的byte数组
	 */
	private byte[] getHeadByte(int dataLen, int size) {
		byte[] buffer = new byte[size];
		Arrays.fill(buffer, 0, buffer.length, (byte) '0');
		byte[] lenByte = (Integer.toString(dataLen, 16)).getBytes();
		System.arraycopy(lenByte, 0, buffer, size - lenByte.length,
				lenByte.length);
		return buffer;

	}

	private Document createErrorDoc(String errMsg) {
		Element root = new Element("result");
		Document doc = new Document(root);
		root.getChildren().add(new Element("success").setText("false"));
		root.getChildren().add(new Element("msg").setText(errMsg));

		return doc;
	}

	private Document createSuccDoc(String msg) {
		Element root = new Element("result");
		Document doc = new Document(root);
		root.getChildren().add(new Element("success").setText("true"));
		root.getChildren().add(new Element("msg").setText(msg));

		return doc;
	}

	/**
	 * 
	 * @param sock
	 * @return
	 * @throws Exception
	 */
	private Document rcvReqDoc(SocketChannel sock) throws Exception {
		SocketChannelHelper sockHelper = SocketChannelHelper.getInstance();
		ByteBuffer buffer = ByteBuffer.allocate(8);

		buffer = sockHelper.readFixPackage(sock, 8, 4000, buffer);

		byte[] head = new byte[8];
		buffer.get(head);
		int xmlLen = this.getRcvXmlLen(head);
		ByteBuffer xmlBuffer = ByteBuffer.allocate(xmlLen);
		xmlBuffer = sockHelper.readFixPackage(sock, xmlLen, 5000, xmlBuffer);
		byte[] xml = new byte[xmlLen];
		xmlBuffer.get(xml);
		Document rcvDoc = XmlUtils.getDocFromByte(xml);
		return rcvDoc;

	}

	/**
	 * 根据接收到head字节串,计算出即将接收的xml的字节串长度
	 * 
	 * @param head
	 * @return 返回接收到的xml数据的长度
	 */
	private int getRcvXmlLen(byte[] head) {
		int size = 0;
		String str = new String(head).substring(2);
		size = Integer.parseInt(str, 16);
		return size;
	}

	/**
	 * Generate random password.
	 */
	private String generatePassword() {
		StringBuffer sb = new StringBuffer(8);
		for (int i = 0; i < 8; i++) {
			int charType = PASS_GEN.nextInt(3);
			switch (charType) {

			// number
			case 0:
				sb.append((char) ('0' + PASS_GEN.nextInt(10)));
				break;

			// uppercase character
			case 1:
				sb.append((char) ('A' + PASS_GEN.nextInt(26)));
				break;

			// lowercase character
			case 2:
				sb.append((char) ('a' + PASS_GEN.nextInt(26)));
				break;
			}
		}
		String password = sb.toString();
		return password;
	}

	private void closeSockChannel(SocketChannel sockChan) {
		try {
			sockChan.close();
		} catch (IOException e) {
			this.m_log.error(e.getMessage());
		}
	}

	/**
	 * 
	 * @override
	 */

	public void setLogFactory(LogFactory logFact) {
		m_log = logFact.getInstance(getClass());
	}

	/**
	 * 
	 * @override
	 */

	public void configure(Configuration config) throws FtpException {
		
	}

	/**
	 * 
	 * @override
	 */

	public void closeSocket() {
		this.isClosed = true;
		try {
			this.channelServer.close();
		} catch (IOException e) {
			this.m_log.error(e.getMessage());
		}
		this.m_log.info("account thread stoped!");
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -