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

POCO 庫中文指南 (十):TCPServer 框架構建自定義 TCP 服務器

     編輯:關於C++

1. TCPServer 架構概覽

POCO TCPServer 採用「連接隊列 + 線程池」模型:

  • 主線程監聽端口,將新連接放入隊列
  • 工作線程池從隊列取連接,創建 TCPServerConnection 並調用 run()
  • 線程池動態伸縮:閒置線程回收,忙碌時創建新線程(可配置最大值)
  • 隊列滿時新連接被悄默拒絕(防禦洪水攻擊)

2. 三大核心類實現

2.1 服務器應用類


class PoechantTCPServer : public ServerApplication {
protected:
    void initialize(Application& self) override {
        ServerApplication::loadConfiguration();
        ServerApplication::initialize(self);
    }
    void uninitialize() override { ServerApplication::uninitialize(); }

    int main(const vector<string>& args) override {
        unsigned short port = config().getInt("PoechantTCPServer.port", 12346);
        string format = config().getString("PoechantTCPServer.format", DateTimeFormat::ISO8601_FORMAT);

        ServerSocket serverSocket(port);
        TCPServer server(new PoechantTCPConnectionFactory(format), serverSocket);
        server.start();
        waitForTerminationRequest();
        server.stop();
        return Application::EXIT_OK;
    }
};

2.2 連接處理類


class PoechantTCPConnection : public TCPServerConnection {
public:
    PoechantTCPConnection(const StreamSocket& s, const string& fmt)
        : TCPServerConnection(s), _format(fmt) {}

    void run() override {
        Application& app = Application::instance();
        app.logger().information("Request from " + socket().peerAddress().toString());
        try {
            Timestamp now;
            string dt(DateTimeFormatter::format(now, _format));
            dt.append("\r\n");
            socket().sendBytes(dt.data(), (int)dt.length());
        } catch (Poco::Exception& e) {
            app.logger().log(e);
        }
    }
private:
    string _format;
};

2.3 連接工廠類


class PoechantTCPConnectionFactory : public TCPServerConnectionFactory {
public:
    PoechantTCPConnectionFactory(const string& fmt) : _format(fmt) {}
    TCPServerConnection* createConnection(const StreamSocket& socket) override {
        return new PoechantTCPConnection(socket, _format);
    }
private:
    string _format;
};

3. 入口與配置


int main(int argc, char** argv) {
    return PoechantTCPServer().run(argc, argv);
}

配置文件 (如 config.properties):


PoechantTCPServer.port = 12346
PoechantTCPServer.format = %Y-%m-%d %H:%M:%S

4. 客戶端測試代碼


#include <iostream>
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/SocketAddress.h"

using Poco::Net::SocketAddress;
using Poco::Net::StreamSocket;

int main() {
    SocketAddress addr("127.0.0.1", 12346);
    StreamSocket socket(addr);
    char buffer[1024];
    while (true) {
        if (socket.available()) {
            int len = socket.receiveBytes(buffer, sizeof(buffer));
            buffer[len] = '\0';
            std::cout << buffer << std::endl;
        }
    }
    return 0;
}

5. 對比:TCPServer vs Reactor

特性TCPServerReactor
並發模型多線程 (線程池)單/少量線程 (事件循環)
適用場景短連接、計算密集型邏輯長連接、高併發、I/O 密集型
編程複雜度低 (同步阻塞風格)中 (異步回調風格)
擴展性受限於線程數極高 (C10K+)

根據業務特性選型:Web 服務、API 网關宜 Reactor;內部 RPC、任務處理宜 TCPServer。

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