ACE 示例2 --- Echo Server

 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模板类来定义自己的Acceptor
2.ACE_Reactor::instance()->handle_events()来实现事件分发
3.在Event_Handle里面使用reactor()->register_handler(this,ACE_Event_Handler::READ_MASK);来注册要关心的事件
4.在Event_Handle中使用peer()来获得Sock_Stream来发送接受数据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值