找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3089|回复: 2

Proactor服务启动失败,求解

[复制链接]
发表于 2009-9-30 11:39:18 | 显示全部楼层 |阅读模式
//////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

为什么?如何解决?
发表于 2009-9-30 14:00:05 | 显示全部楼层

回复 #1 rotar 的帖子

ACE和MFC结合的时候要在
BOOL CProactorClientDlg::OnInitDialog()
{
        CDialog::OnInitDialog();
        ACE::init();//加上这句话
。。。
}
 楼主| 发表于 2009-10-1 10:24:39 | 显示全部楼层
呵呵,谢谢啦
我看你的贴子,在和我弄差不多的东西,如果方便可以联系下
QQ:6811201
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-23 13:57 , Processed in 0.020983 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表