ACE_Reactor模式(handle_input的工作)V1.0

CalmReason發表於2016-02-29

handle_input的呼叫時機

我們通過Acceptor-Connector模式一(Acceptor的工作)知道了接受器主要是當連線建立之後建立服務處理器,並啟動服務處理的open方法來實現正式通訊流程的。

所以,open方法中總是有跟socket有關的read,write方法的呼叫。當這些read,write方法執行完畢之後,就會呼叫handle_read方法或handle_write方法。


handle_input的工作

由於handle_input函式是處理read操作的後事的,所以這裡涉及到還要不要有後續:

(1)如果read完畢就結束流程,那這裡只需要返回-1,由反應器來呼叫服務處理器的handle_close()方法,而這個方法的預設實現就是delete this

(2)如果read完畢並不結束流程,那就繼續執行其他流程,比如用write操作給對端寫返回資料。

下面的例子僅僅展示handle_input什麼也不做,用於結束流程的情況:

server.cpp

功能:收到客戶端的資料之後就列印出來,然後結束流程

#include <ace/Log_Msg.h>
#include "ace/Svc_Handler.h"
#include <ace/Acceptor.h>
#include "ace/SOCK_Acceptor.h"
#include "ace/INET_Addr.h"
#include "ace/Reactor.h"
#include "ace/Message_Block.h"

class My_Time_Server_Handler : public ACE_Svc_Handler<ACE_SOCK_Stream,ACE_NULL_SYNCH>
{
public:
	~My_Time_Server_Handler();
	//由接收器在接收到對端的連線請求之後呼叫此方法
	virtual int open(void *)
	{
		ACE_DEBUG((LM_DEBUG,"one client connection established.\n"));
		//當有TCP連線收到了資料之後,會呼叫這個類的handle_input()方法來處理
		//所以需要實現handle_input()方法
		ACE_Reactor::instance()->register_handler(this,ACE_Event_Handler::READ_MASK);

		ACE_Message_Block* blk = new ACE_Message_Block(1024);
		this->peer().recv_n(blk->wr_ptr(),1024);
		ACE_DEBUG((LM_DEBUG,"服務端收到:%s\n",blk->rd_ptr()));

		return 0;// OK
	}
	//這個方法僅僅是被反應器呼叫,但是具體做什麼事,由當前類自己說了算
	//當前實現是將收到的資料列印出來
	virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE)
	{
		ACE_DEBUG((LM_DEBUG,"服務處理器read完畢\n"));
		//此處返回-1會讓反應器呼叫服務處理器的handle_close()方法,
		//而這個方法的預設實現就是delete this
		return -1;
	}

};

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

int main(int argc, char *argv[])
{
	ACE_INET_Addr local_addr(1500);

	ACE_Acceptor<My_Time_Server_Handler,ACE_SOCK_Acceptor> acceptor;

	acceptor.open(local_addr,ACE_Reactor::instance());
	//截過連線資訊
	ACE_Reactor::instance()->run_reactor_event_loop();

	return 0;
}
client.cpp

功能:向服務端傳送一個字串,由服務端負責列印出來

#include <ace/Log_Msg.h>
#include <ace/SOCK_Connector.h>
#include "ace/INET_Addr.h"
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
	ACE_INET_Addr addr(1500,"127.0.0.1"); //remote address
	ACE_SOCK_Connector client_connetor; // connetor for socket client
	ACE_SOCK_Stream sock_stream; // stream is for socket read/write

	if(client_connetor.connect(sock_stream,addr)==-1) //connect to remote address
	{
		ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) %p\n"),ACE_TEXT ("connection failed!")));
		return -1;
	}
	string command_to_server("give_me_time");
	int send_lenth;
	if ((send_lenth =sock_stream.send_n(command_to_server.c_str(),command_to_server.size())) == -1)
	{
		ACE_DEBUG((LM_DEBUG,"客戶端傳送獲取時間命令失敗!\n"));
	}

	if (sock_stream.close () == -1) //close the connection
	{
		ACE_ERROR ((LM_ERROR,ACE_TEXT ("(%P|%t) %p\n"),ACE_TEXT ("sock close")));
		return -1;
	}
	return 0;
}



相關文章