基于ACE reactor_echo_server实现

/*
 * reactor_echo_server.cpp

#include <ace/Event_Handler.h>
#include <ace/SOCK_Stream.h>
#include <ace/SOCK_Acceptor.h>
#include <ace/Timer_Queue.h>
#include <ace/Reactor.h>
#include <ace/Log_Msg.h>
#include <ace/Singleton.h>
#include <ace/Dev_Poll_Reactor.h>

#include <string>
#include <map>

typedef int (*CmdHandler)(const std::string& param, ACE_SOCK_Stream& sock);

class CmdHandlers {
public:
	bool registerCmdHandler(const std::string& cmd, CmdHandler h) {
		handlers.insert(std::make_pair(cmd, h));
		return true;
	}

	CmdHandler getCmdHandler(const std::string& cmd) {
		std::map<std::string, CmdHandler>::iterator i = handlers.find(cmd);
		return i != handlers.end() ? i->second : CmdHandler();
	}

private:
	std::map<std::string, CmdHandler> handlers;
};

typedef ACE_Singleton<CmdHandlers, ACE_Null_Mutex> CmdHandlerInst;

static const ACE_Time_Value MAX_INTERVAL(300);

class Connection: public ACE_Event_Handler {
public:

	Connection() {

	}

	~Connection() {
		ACE_DEBUG((LM_DEBUG, "~Connection()\n"));
	}

	int open(ACE_Reactor* react) {

		const char* welcome = "220 Welcome.\r\n";
		if (sock.send(welcome, ACE_OS::strlen(welcome)) == -1)
			ACE_ERROR_RETURN((LM_ERROR, "%p\n", "sock.send()"), -1);

		this->reactor(react);

		if (reactor()->schedule_timer(this, 0, ACE_Time_Value::zero,
				MAX_INTERVAL) == -1)
			ACE_ERROR_RETURN((LM_ERROR, "%p\n", "reactor().schedule_timer()"),
					-1);

		lastMsgTime = reactor()->timer_queue()->gettimeofday();

		return reactor()->register_handler(this, READ_MASK);
	}

	ACE_SOCK_Stream& socket() {
		return sock;
	}

	virtual ACE_HANDLE get_handle() const {
		return sock.get_handle();
	}

	virtual int handle_input(ACE_HANDLE fd) {
		ssize_t len = sock.recv(buf, sizeof buf);
		if (len <= 0) {
			if (len != 0)
				ACE_ERROR_RETURN((LM_ERROR, "%p\n", "sock.recv()"), -1);
		}

		lastMsgTime = reactor()->timer_queue()->gettimeofday();

		char* pos = ACE_OS::strstr(buf, "\r\n");
		if (pos)
			*pos = '\0';

		pos = ACE_OS::strchr(buf, ' ');
		std::string cmd, param;
		if (pos) {
			cmd = std::string(buf, pos);
			param = std::string(pos + 1);
		} else
			cmd = buf;

		CmdHandler h = CmdHandlerInst::instance()->getCmdHandler(cmd);
		if (h)
			return h(param, sock);
		else {
			const char* reply = "500 FTP: command not recognized.\r\n";
			if (sock.send_n(reply, ACE_OS::strlen(reply)) == -1)
				ACE_ERROR_RETURN((LM_ERROR, "%p\n", "sock.send_n()"), -1);
		}

//		if (sock.send_n(buf, len) != len) {
//			ACE_ERROR((LM_ERROR, "%p\n", "sock.send_n()"));
//			return -1;
//		}

		return 0;
	}

	virtual int handle_timeout(const ACE_Time_Value ¤t_time,
			const void *act) {
		if (current_time - lastMsgTime > MAX_INTERVAL)
			reactor()->remove_handler(this, READ_MASK);

		return 0;
	}

	virtual int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask) {
		if (handle == ACE_INVALID_HANDLE)
			return 0;

//		ACE_Reactor_Mask m = ALL_EVENTS_MASK | DONT_CALL;
		reactor()->cancel_timer(this);
//		reactor()->remove_handler(this, m);

		sock.close();

		delete this;

		return 0;
	}

private:
	ACE_SOCK_Stream sock;
	char buf[512];
	ACE_Time_Value lastMsgTime;
};

// ----------------------------------------------------------------------------

class Acceptor: public ACE_Event_Handler {
public:
	Acceptor() {

	}

	~Acceptor() {
		ACE_DEBUG((LM_DEBUG, "~Acceptor()\n"));
	}

	int open(ACE_Reactor* react, unsigned short port) {
		this->reactor(react);

		ACE_INET_Addr addr;
		if (addr.set(port) == -1)
			ACE_ERROR_RETURN((LM_ERROR, "%p\n", "addr.set()"), -1);

		if (acceptor.open(addr, 1) == -1)
			ACE_ERROR_RETURN((LM_ERROR, "%p\n", "acceptor.open()"), -1);

		return reactor()->register_handler(this, ACCEPT_MASK);
	}

	virtual ACE_HANDLE get_handle() const {
		return acceptor.get_handle();
	}

	virtual int handle_input(ACE_HANDLE fd) {
		Connection* con = new Connection();
		if (acceptor.accept(con->socket()) == -1) {
			ACE_ERROR((LM_ERROR, "%p\n", "acceptor.accept()"));
			delete con;
		} else {
			if (con->open(reactor()) == -1)
				delete con;
		}
		return 0;
	}

private:
	ACE_SOCK_Acceptor acceptor;
};

int main() {

	ACE_Reactor* r = new ACE_Reactor(new ACE_Dev_Poll_Reactor, true);
	ACE_Reactor::instance(r);

	Acceptor acceptor;
	if (acceptor.open(ACE_Reactor::instance(), 9988) == -1)
		return 1;

	return ACE_Reactor::instance()->run_reactor_event_loop();
}

// ----------------------------------------------------------------------------

int handleCmdSYST(const std::string& param, ACE_SOCK_Stream& sock) {
	static const char* reply = "215 UNIX Type: L8\r\n";
	if (sock.send(reply, ACE_OS::strlen(reply)) == -1)
		ACE_ERROR_RETURN((LM_ERROR, "%p\n", "sock.send()"), -1);

	return 0;
}


bool a = CmdHandlerInst::instance()->registerCmdHandler("SYST", handleCmdSYST);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值