/*
主要功能是,将客户端发送转发到其他所有客户端
*/
#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