(转)ACE 示例2 --- Echo Server

    技术2022-05-20  60

    Echo server就是那种提供回显服务的程序,就是收到什么,然后就发送什么的程序。两种实现方法1.Per client Per Thread (每个连接每个线程来处理)这种方式比较简单,易于实现。缺点是如果有大量的连接,必然占用过量的系统资源。#ifdef _DEBUG #pragma comment(lib,"ACED.lib") #else #pragma comment(lib,"ACE.lib") #endif #include <ace/OS_main.h> #include <ace/ACE.h> #include <ace/Log_Msg.h> #include <ace/SOCK_Acceptor.h> #include <ace/Thread.h> DWORD worker(void *arg) { ACE_SOCK_Stream *pStream =(ACE_SOCK_Stream *) arg; char buffer[32] = {0}; int len; while( (len = pStream->recv(buffer,sizeof(buffer)-1)) >0) { if(pStream->send_n(buffer,len)<=0) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) %p/n"), ACE_TEXT ("send failed"))); break; } } ACE_INET_Addr raddr; pStream->get_remote_addr(raddr); ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) close:%s %d/n"),raddr.get_host_addr(),raddr.get_port_number())); pStream->close(); delete pStream; return 0; } int main(int argc, char *argv[]) { ACE_INET_Addr addr(1500); ACE_SOCK_Acceptor server; if(server.open(addr)==-1) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) %p/n"), ACE_TEXT ("bind failed"))); return 1; } ACE_SOCK_Stream *pStream = 0; while((pStream =new ACE_SOCK_Stream()) && server.accept(*pStream)!=-1) { ACE_INET_Addr raddr; pStream->get_remote_addr(raddr); ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) connect:%s %d/n"),raddr.get_host_addr(),raddr.get_port_number())); ACE_Thread::spawn(worker,pStream); } server.close(); return 0; }

     

    说明:      ACE_Thread用来启动thread,当有client连上来的时候,启动worker thread来处理。

    2.事件模型socket里面是有select机制,ACE也提供了这种方式。概念:Event_Handler:有事件来临的时候的处理器Reactor:事件管理,负责管理Event_Hanlde和分发事件Acceptor负责连接Event_Handle,Reactor和Sock_Acceptor#ifdef _DEBUG #pragma comment(lib,"ACED.lib") #else #pragma comment(lib,"ACE.lib") #endif #include <ace/OS_main.h> #include <ace/ACE.h> #include <ace/Svc_Handler.h> #include <ace/Acceptor.h> #include <ace/Log_Msg.h> #include <ace/SOCK_Acceptor.h> #include <ace/Thread.h> class My_Svc_Handler: public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH> { public: int open(void*) { ACE_INET_Addr raddr; peer().get_remote_addr(raddr); ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) connect:%s %d %d/n"),raddr.get_host_addr(),raddr.get_port_number(),this)); reactor()->register_handler(this,ACE_Event_Handler::READ_MASK); return 0; } int handle_input(ACE_HANDLE) { char buffer[32] = {0}; int len = peer().recv(buffer,sizeof(buffer)-1); if(len>0) { if(peer().send_n(buffer,len)<=0) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) %p/n"), ACE_TEXT ("send failed"))); return -1; //must return -1 to call handle_close } return 0; } else { return -1; //must return -1 to call handle_close } } int handle_close(ACE_HANDLE handle,ACE_Reactor_Mask close_mask) { ACE_INET_Addr raddr; peer().get_remote_addr(raddr); ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) close:%s %d/n"),raddr.get_host_addr(),raddr.get_port_number())); peer().close(); return 0; } }; typedef ACE_Acceptor<My_Svc_Handler,ACE_SOCK_ACCEPTOR> MyAcceptor; int main(int argc, char *argv[]) { ACE_INET_Addr addr(1500); MyAcceptor server; if(server.open(addr)==-1) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) %p/n"), ACE_TEXT ("bind failed"))); return 1; } while(1){ ACE_Reactor::instance()->handle_events(); } server.close(); return 0; }

     

    说明:1.使用ACE_Acceptor模板类来定义自己的Acceptor2.ACE_Reactor::instance()->handle_events()来实现事件分发3.在Event_Handle里面使用reactor()->register_handler(this,ACE_Event_Handler::READ_MASK);来注册要关心的事件4.在Event_Handle中使用peer()来获得Sock_Stream来发送接受数据。


    最新回复(0)