自己写的ACE的Proactor例子

/*
主要功能是,将客户端发送转发到其他所有客户端
*/
#include "ace/OS_main.h"
#include "ace/Proactor.h"
#include "ace/Asynch_Acceptor.h"
#include "ace/INET_Addr.h"
#include "ace/OS.h"
#include "ace/SOCK_Connector.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/SOCK_Stream.h"
#include "ace/Message_Block.h"
#include "ace/Containers.h"

#define LISTEN_PORT 4200

ACE_DLList<ACE_Asynch_Write_Stream> wList;

class Receiver:public ACE_Service_Handler
{
public:
 Receiver();
 ~Receiver(void);

 virtual void open(ACE_HANDLE new_handle,ACE_Message_Block &message_block);
protected:
 int init_read_stream(void);
 virtual void handle_read_stream(const ACE_Asynch_Read_Stream::Result &result);
 virtual void handle_write_stream(const ACE_Asynch_Write_Stream::Result &result);
private:
 ACE_Asynch_Read_Stream rs_;
 // rs (read stream): for reading from a socket.
 ACE_Asynch_Write_Stream ws_;

 ACE_HANDLE handle_;
 // Handle for IO to remote peer.
    ACE_TCHAR peer_name[MAXHOSTNAMELEN];
 ACE_INET_Addr remote_address;
 ACE_INET_Addr local_address;
};

Receiver::Receiver(void):handle_(ACE_INVALID_HANDLE)
{
};

Receiver::~Receiver(void)
{
 if(this->handle()!=ACE_INVALID_HANDLE)
  ACE_OS::closesocket(this->handle());
};

int Receiver::init_read_stream(void)
{
 ACE_Message_Block *mb=0;
 ACE_NEW_RETURN(mb,ACE_Message_Block(512),-1);

 if(rs_.read(*mb,mb->space())==-1)
 {
  ACE_ERROR_RETURN ((LM_ERROR,
   "%p/n",
   "ACE_Asynch_Read_Stream::read"),
   -1);
 }
 return 0;
};


void Receiver::open(ACE_HANDLE new_handle,ACE_Message_Block &message_block)
{
 this->handle_=new_handle;

 if(rs_.open(*this))
 {
  ACE_ERROR ((LM_ERROR,
   "%p/n",
   "ACE_Asynch_Read_Stream::open"));
  return;
 }

 if(ws_.open(*this))
 {
  ACE_ERROR ((LM_ERROR,
   "%p/n",
   "ACE_Asynch_Write_Stream::open"));
  return;
 }
 if (init_read_stream()==-1)
  return;

 wList.insert_tail(&ws_);
 this->addresses(remote_address,local_address);
 remote_address.addr_to_string(peer_name,MAXHOSTNAMELEN); 
    ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%t)新连接:%s /n"),peer_name));
};

void Receiver::handle_read_stream(const ACE_Asynch_Read_Stream::Result &result)
{
 if (result.success()&&result.bytes_transferred()!=0)
 {

  ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%t)%s:%s /n"),peer_name,result.message_block().rd_ptr()));
  //将信息加入公共消息队列
  //如何将此信息转发到所有客户端?
  ACE_DLList_Iterator<ACE_Asynch_Write_Stream> iter(wList);
  while(!iter.done())
  {
   if (iter.next()->write(*result.message_block().duplicate(),
    result.message_block().length())==-1)
   {
    ACE_ERROR ((LM_ERROR,
     "%p/n",
     "ACE_Asynch_Write_Stream::write"));
   }
   iter++;
  }
  result.message_block().release();
  if (init_read_stream()==-1)
   return;
 }
 else
 {
  result.message_block().release();
  ACE_DLList_Iterator<ACE_Asynch_Write_Stream> iter(wList);
  while (!iter.done ())
  {
   if(&ws_==iter.next())
   {
    iter.remove();
    break;
   }
   iter++;
  }
  delete this;
 }
};

void Receiver::handle_write_stream(const ACE_Asynch_Write_Stream::Result &result)
{
 result.message_block().release();
 return;
};

 

int ACE_TMAIN(int argc,char *argv[])
{
 // Note: acceptor parameterized by the Receiver.
 ACE_Asynch_Acceptor<Receiver> acceptor;
 
 if(acceptor.open(ACE_INET_Addr(4200),
  0,
  1)==-1)
 {
  return -1;
 }

 ACE_Proactor::instance()->proactor_run_event_loop();
 return 0;
};

现在有几个问题:

1、如果记录所有连接的客户端?

2、Proactor如何ACE中ACE_Task结合?

3、本来想用STL的List记录 ACE_Asynch_Write_Stream,但是ACE_Asynch_Write_Stream没有实现==,所以使用迭代就用问题,所以只好用ACE中的容器ACE_DLList?

ACE的好处就是跨平台,此程序在Linux上编译,就可以运行,但是会报ACE_POSIX_AIOCB_Proactor::Max Number of AIOs=1024

看资料说Linux上最大支持1024异步IO

linux编译:

g++ -o DisServer.exe  DistributeServer.cpp -I /home/ace/ACE_wrappers -l ACE -L /home/ace/ACE_wrappers/ace

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值