//////netserver.h
#pragma once
#include "ace/ACE.h"
#include "ace/Asynch_Connector.h"
#include "ace/Asynch_IO.h"
#include "ace/Message_Block.h"
#include "ace/Null_Mutex.h"
#include "ace/Proactor.h"
#include "ace/Singleton.h"
#include "ace/Synch_Traits.h"
#include "ace/Task.h"
#include <ace/Asynch_Acceptor.h>
#include <ace/SOCK_SEQPACK_Association.h>
#include <fstream>
class CServer_Handler : public ACE_Service_Handler
{
public:
CServer_Handler(){};
~CServer_Handler(){
if (this->handle () != ACE_INVALID_HANDLE)
ACE_OS::closesocket (this->handle ());
};
virtual void open (ACE_HANDLE new_handle,
ACE_Message_Block &message_block);
protected:
ACE_Asynch_Read_Stream reader_;
ACE_Asynch_Write_Stream writer_;
void start_write (ACE_Message_Block *mblk = 0);
virtual void handle_read_stream
(const ACE_Asynch_Read_Stream::Result &result);
virtual void handle_write_stream
(const ACE_Asynch_Write_Stream::Result &result);
};
class NetServer
{
public:
NetServer(void);
~NetServer(void);
bool ServerStart();
bool ServerStop();
int GetPort(){return m_iport;};
void SetPort(int port){m_iport=port;};
private:
int m_iport;
std::ofstream myostream ;
};
=====================================================================
//////netserver.cpp
#include "StdAfx.h"
#include "NetServer.h"
typedef ACE_Asynch_Acceptor<CServer_Handler> MyAcceptor;
NetServer::NetServer(void):m_iport(2009)
{
}
NetServer::~NetServer(void)
{
}
bool NetServer::ServerStart()
{
ACE_INET_Addr addr(m_iport);
const char *filename = "d:\\output.log";
myostream.open(filename,ios::out | ios::trunc);
if (myostream.bad ())
return false;
ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM);
ACE_LOG_MSG->msg_ostream (&myostream);
MyAcceptor server;
if(server.open(addr)==-1)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("bind failed")));
return false;
}
while(1){
ACE_Proactor::instance ()->proactor_run_event_loop ();
}
return true;
}
bool NetServer::ServerStop()
{
ACE_Proactor::instance()->proactor_end_event_loop();
myostream.close();
return true;
}
//////////////////////////////////////////////////////////
void CServer_Handler::open(ACE_HANDLE new_handle, ACE_Message_Block &message_block)
{
this->handle (new_handle);
if (this->reader_.open (*this) != 0 || this->writer_.open (*this) != 0 )
{
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"),ACE_TEXT ("Service open")));
delete this;
return;
}
//获取远程地址
ACE_SOCK_SEQPACK_Association ass=ACE_SOCK_SEQPACK_Association(new_handle);
size_t addr_size=/*sizeof(ACE_INET_Addr)*/512;
ACE_INET_Addr addr_r1;
ACE_INET_Addr addr_l1;
ass.get_local_addrs(&addr_l1,addr_size);
ass.get_remote_addrs(&addr_r1,addr_size);
TRACE("B remote %s:%d local %s:%d\n",addr_r1.get_host_name(),addr_r1.get_port_number(),addr_l1.get_host_name(),addr_l1.get_port_number());
//如果同时传数据过来,伪造读结果,呼叫读事件
if (message_block.length()>0)
{
// 复制消息块
ACE_Message_Block &duplicate = *message_block.duplicate ();
// 伪造读结果,以便进行读完成回调
ACE_Asynch_Read_Stream_Result_Impl *fake_result =
ACE_Proactor::instance ()->create_asynch_read_stream_result (this->proxy (),
this->handle_,
duplicate,
1024,
0,
ACE_INVALID_HANDLE,
0,
0);
size_t bytes_transferred = message_block.length ();
// Accept事件处理完成,wr_ptr指针会被向前移动,将其移动到开始位置
duplicate.wr_ptr (duplicate.wr_ptr () - bytes_transferred);
// 这个方法将调用回调函数
fake_result->complete (message_block.length (), 1, 0);
// 销毁伪造的读结果
delete fake_result;
}
ACE_Message_Block *mb;
ACE_NEW_NORETURN (mb, ACE_Message_Block (1024));
if (this->reader_.read (*mb, mb->space ()) != 0)
{
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"),ACE_TEXT ("Service begin read")));
mb->release ();
delete this;
return;
}
}
void CServer_Handler::handle_read_stream(const ACE_Asynch_Read_Stream::Result &result)
{
ACE_Message_Block &mb = result.message_block ();
if (!result.success () || result.bytes_transferred () == 0)
{
mb.release ();
delete this;
}
else
{
char szText[1024];
int nRecvLen = (int)mb.length();
memcpy( szText, mb.base(), nRecvLen);
szText[nRecvLen] = '\0';
ACE_DEBUG(( LM_DEBUG, ACE_TEXT("Recv text:%s!\n"), szText ));
ACE_Message_Block *new_mb;
ACE_NEW_NORETURN (new_mb, ACE_Message_Block (1024));
this->reader_.read (*new_mb, new_mb->space ());
}
return;
}
void CServer_Handler::handle_write_stream(const ACE_Asynch_Write_Stream::Result &result)
{
ACE_Message_Block &mb = result.message_block ();
mb.release ();
return;
}
typedef ACE_Asynch_Acceptor<CServer_Handler> MyAcceptor;
int main(int argc, char *argv[])
{
ACE_INET_Addr addr(1500);
MyAcceptor server;
const char *filename = "d:\\output.log";
std::ofstream myostream (filename, ios::out | ios::trunc);
if (myostream.bad ())
return -1;
ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM);
ACE_LOG_MSG->msg_ostream (&myostream);
if(server.open(addr)==-1)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("bind failed")));
return 1;
}
while(1){
ACE_Proactor::instance ()->proactor_run_event_loop ();
}
myostream.close();
return 0;
}
=====================================================================
程序可以正常运行,
把class NetServer改成class AFX_EXT_CLASS GPTNetServer导出为dll
在一个对话框中引入
NetServer server;
server.ServerStart();
失败,输出的信息
ACE_OS::socket: WSA Startup not initialized
(3728|2060) bind failed: WSA Startup not initialized
为什么?如何解决? |