首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

ACE Proactor UDP 異步通信:單次收發與定時多目標廣播完整實現

     編輯:C++ 入門

ACE Proactor 模式簡介

ACE Proactor 實現 **Proactor 模式**(異步 I/O 完成通知),與 Reactor(同步事件通知)不同。UDP 無連接,無 Acceptor/Connector,直接用 ACE_Asynch_Read_Dgram/ACE_Asynch_Write_Dgram 綁定 ACE_SOCK_Dgram 並註冊完成處理器。

單次發送/接收示例

發送端

class Sender : public ACE_Handler {
    ACE_SOCK_Dgram sock_;
    ACE_Asynch_Write_Dgram writer_;
    const char *compKey_ = "SenderKey", *act_ = "SenderAct";
public:
    int open(const ACE_TCHAR *host, u_short port) {
        sock_.open(ACE_INET_Addr::sap_any);
        writer_.open(*this, sock_.get_handle(), compKey_, ACE_Proactor::instance());
        // 構造兩塊數據:頭 + 體
        ACE_Message_Block *hdr = new ACE_Message_Block(100);
        hdr->copy("To be or not to be.", 20);
        ACE_Message_Block *body = new ACE_Message_Block(100);
        memset(body->wr_ptr(), 'X', 100); body->wr_ptr(100);
        hdr->cont(body);
        // 異步發送
        ACE_INET_Addr dst(port, host);
        size_t sent; int rc = writer_.send(hdr, sent, 0, dst, act_);
        return (rc == -1) ? -1 : 0;
    }
    virtual void handle_write_dgram(const ACE_Asynch_Write_Dgram::Result &r) {
        r.message_block()->release(); // 釋放鏈
        // 可檢查 r.bytes_transferred(), r.success() 等
    }
};

接收端

class Receiver : public ACE_Service_Handler {
    ACE_SOCK_Dgram sock_;
    ACE_Asynch_Read_Dgram reader_;
    const char *compKey_ = "RecvKey", *act_ = "RecvAct";
public:
    int open_addr(const ACE_INET_Addr &local) {
        sock_.open(local);
        reader_.open(*this, sock_.get_handle(), compKey_, ACE_Proactor::instance());
        ACE_Message_Block *hdr = new ACE_Message_Block(1024); hdr->size(20);
        ACE_Message_Block *body = new ACE_Message_Block(1024);
        hdr->cont(body);
        size_t recvd; int rc = reader_.recv(hdr, recvd, 0, PF_INET, act_);
        return (rc == -1) ? -1 : 0;
    }
    virtual void handle_read_dgram(const ACE_Asynch_Read_Dgram::Result &r) {
        if (r.success() && r.bytes_transferred()) {
            for (auto mb = r.message_block(); mb; mb = mb->cont()) {
                // mb->length() 有效長度,mb->rd_ptr() 數據指針
            }
        }
        r.message_block()->release();
    }
};

定時多目標廣播

需求:每隔 interval 秒,讀取文件內容,發送到配置文件列出的多個 IP:Port。

關鍵類設計

class Broadcaster : public ACE_Handler, public ACE_Event_Handler {
    ACE_SOCK_Dgram sock_;
    ACE_Asynch_Write_Dgram writer_;
    long timerId_;
    int intervalSec_;
    vector<string> targets_; // "ip:port"
    string contentFile_;
public:
    Broadcaster(int interval) : intervalSec_(interval) {}
    int open(const ACE_TCHAR *localHost, u_short localPort) {
        sock_.open(ACE_INET_Addr::sap_any);
        writer_.open(*this, sock_.get_handle(), "BcastKey", ACE_Proactor::instance());
        // 註冊定時器
        reactor(ACE_Reactor::instance());
        timerId_ = reactor()->schedule_timer(this, 0,
            ACE_Time_Value(intervalSec_), ACE_Time_Value(intervalSec_));
        return 0;
    }
    virtual int handle_timeout(const ACE_Time_Value&, const void*) {
        // 讀取配置與內容
        readTargets("targets.cfg");   // 每行 "ip port"
        string content = readFile(contentFile_);
        // 逐目標發送
        for (auto &t : targets_) {
            sendOne(t, content);
        }
        return 0;
    }
    void sendOne(const string& target, const string& msg) {
        ACE_Message_Block *mb = new ACE_Message_Block(msg.size()+1);
        mb->copy(msg.c_str(), msg.size()+1);
        ACE_INET_Addr addr(target.c_str());
        size_t sent; writer_.send(mb, sent, 0, addr, "BcastAct");
    }
    virtual void handle_write_dgram(const ACE_Asynch_Write_Dgram::Result &r) {
        r.message_block()->release();
    }
};

主程序

int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) {
    ACE_Proactor::close_singleton();
    ACE_WIN32_Proactor *impl = new ACE_WIN32_Proactor(0, 1);
    ACE_Proactor::instance(new ACE_Proactor(impl, 1), 1);
    ACE_Reactor::instance()->register_handler(impl, impl->get_handle());

    Broadcaster b(10); // 10 秒間隔
    b.open(ACE_TEXT("0.0.0.0"), 0);
    ACE_Reactor::instance()->run_event_loop(); // 永久運行
    return 0;
}

配置文件示例

# targets.cfg
192.168.1.100 5000
192.168.1.101 5000
# content.txt
...data...

總結

ACE Proactor UDP 異步通信核心在於:
1. ACE_Asynch_Read_Dgram/Write_Dgram 綁定 ACE_SOCK_Dgram 與完成處理器。
2. 數據塊鏈 (Message_Block::cont) 支持散佈/聚集讀寫。
3. 定時廣播結合 ACE_Event_Handler::handle_timeout + Reactor::schedule_timer。
4. 完成回調中**必須釋放 Message_Block 鏈**,否則洩漏。
此模型適用於高性能 UDP 服務器/客戶端、日誌廣播、心跳檢測等場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved