用ACE的Reactor模式实现网络通讯的例子

45 篇文章 0 订阅
38 篇文章 0 订阅

用ACE的Reactor模式实现网络通讯的例子,不罗嗦,直接上代码。

服务器代码:

#include <ace/Reactor.h>
#include <ace/SOCK_Connector.h> 
#include <ace/SOCK_Acceptor.h> 
#include <ace/Auto_Ptr.h>


class ClientService : public ACE_Event_Handler
{
public:
    ACE_SOCK_Stream &peer (void) { return this->sock_; }

    int open (void)
    {
        //注册读就绪回调函数
        return this->reactor ()->register_handler(this, ACE_Event_Handler::READ_MASK);
    }

    virtual ACE_HANDLE get_handle (void) const { return this->sock_.get_handle (); }

    virtual int handle_input (ACE_HANDLE fd )
    {
        int rev = peer().recv(buf,sizeof(buf));
        if(rev<=0)
            return -1;
		buf[rev] = '\0';
		printf("recv: %s",buf);
		strcpy(buf,"hello,Client\n");
        peer().send(buf,strlen(buf)); //向客户端发送信息。
        return 0;
    }

    // 释放相应资源
virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask mask)
    {
        if (mask == ACE_Event_Handler::WRITE_MASK)
            return 0;
        mask = ACE_Event_Handler::ALL_EVENTS_MASK |
            ACE_Event_Handler::DONT_CALL;
        this->reactor ()->remove_handler (this, mask);
        this->sock_.close ();
        delete this;    //socket出错时,将自动删除该客户端,释放相应资源
        return 0;
    }

protected:
    char buf[100];
    ACE_SOCK_Stream sock_;
};


class ClientAcceptor : public ACE_Event_Handler
{
public:
    virtual ~ClientAcceptor (){this->handle_close (ACE_INVALID_HANDLE, 0);}

    int open (const ACE_INET_Addr &listen_addr)
    {
        if (this->acceptor_.open (listen_addr, 1) == -1)
        {
            printf("open port fail\n");
            return -1;
        }
        //注册接受连接回调事件
        return this->reactor ()->register_handler(this, ACE_Event_Handler::ACCEPT_MASK);
    }

    virtual ACE_HANDLE get_handle (void) const
    { return this->acceptor_.get_handle (); }

    virtual int handle_input (ACE_HANDLE fd )
    {
        ClientService *client = new ClientService();
        auto_ptr<ClientService> p (client);

        if (this->acceptor_.accept (client->peer ()) == -1)
        {
            printf("accept client fail\n");
            return -1;
        }
        p.release ();
        client->reactor (this->reactor ());
        if (client->open () == -1)
            client->handle_close (ACE_INVALID_HANDLE, 0);
        return 0;
    }
    
    virtual int handle_close (ACE_HANDLE handle,
        ACE_Reactor_Mask close_mask)
    {
        if (this->acceptor_.get_handle () != ACE_INVALID_HANDLE)
        {
            ACE_Reactor_Mask m = ACE_Event_Handler::ACCEPT_MASK |
                ACE_Event_Handler::DONT_CALL;
            this->reactor ()->remove_handler (this, m);
            this->acceptor_.close ();
        }
        return 0;
    }

protected:
    ACE_SOCK_Acceptor acceptor_;
};

int main(int argc, char *argv[]) 
{
    ACE_INET_Addr addr(3000,"127.0.0.1");
    ClientAcceptor server;
    server.reactor(ACE_Reactor::instance());
    server.open(addr);

    while(true)
    {
        ACE_Reactor::instance()->handle_events(); 
    }

    return 0; 
} 


客户端代码:

#include "ace/Reactor.h"
#include "ace/SOCK_Connector.h"

#include <string>
#include <iostream>
using namespace std;

class MyClient:public ACE_Event_Handler 
{
public:
    bool open()
    {
        ACE_SOCK_Connector connector;
        ACE_INET_Addr addr(3000,"127.0.0.1");
        ACE_Time_Value timeout(5,0);
        if(connector.connect(peer,addr,&timeout) != 0)
        {
            cout<<endl<<"connect fail.";
            return false;
        }
        ACE_Reactor::instance()->register_handler(this,ACE_Event_Handler::READ_MASK);
        cout<<endl<<"connected.";
		strcpy(buf, "hello,Server\n");
		peer.send(buf,strlen(buf));
        return true;
    }

    ACE_HANDLE get_handle(void) const
    {
        return peer.get_handle();
    }

    int handle_input (ACE_HANDLE fd)
    {
        int rev=0;
        ACE_Time_Value timeout(5,0);
        if((rev=peer.recv(buf,sizeof(buf),&timeout))>0)
        {
            buf[rev]='\0';
            cout<<endl<<"recv: "<<buf<<endl;
        }
        return 3;
    }

private:
    ACE_SOCK_Stream peer;
    char buf[100];
};

int main(int argc, char *argv[]) 
{
    MyClient client;
    client.open();

    while(true)
    {
        ACE_Reactor::instance()->handle_events(); 
    }

    return 0; 
}


分别编译运行(先运行服务端,后运行客户端)下面是执行结果。

服务器:

recv: hello,Server

客户端:

connected.
recv: hello,Client

 

参考:

http://www.cnblogs.com/TianFang/archive/2006/12/13/591332.html

http://www.cnblogs.com/TianFang/archive/2006/12/18/595938.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值