You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于PhotonLib开发后端时TCP服务器端口绑定失败(core dumped)求助

基于PhotonLib开发后端时TCP服务器端口绑定失败(core dumped)求助

嘿,我仔细看了你的代码,立刻就找到导致端口绑定失败并core dump的原因了!

问题核心:重复绑定同一个端口

你在start()函数里启动了8个worker线程,每个线程都会进入worker_loop(),而每个worker线程都创建了一个全新的TCP Socket Server,然后尝试绑定同一个8080端口。

TCP协议的规则是:同一个端口在同一时间只能被一个Socket监听实例绑定(除非开启SO_REUSEPORT选项,但这不是常规Web服务的做法)。第一个worker线程绑定端口会成功,但后面的7个线程都会绑定失败,抛出std::runtime_error,最终导致程序core dump。

看一下你worker_loop()里的问题代码:

void HttpServer::worker_loop() {
    // 每个线程都新建一个server,重复绑定端口!
    auto server = photon::net::new_tcp_socket_server();
    if (!server->bind(options_.port)) {
        throw std::runtime_error("Failed to bind TCP server");
    }
    if (!server->listen()) {
        throw std::runtime_error("Failed to listen");
    }
    // ... 后续accept逻辑
}

修复方案:单监听Socket + 多Worker线程处理连接

正确的做法是只创建并绑定一次监听Socket Server,然后让所有worker线程共享这个监听实例,共同处理客户端的连接请求。

步骤1:修改HttpServer类,添加监听Server成员

在server.hpp的HttpServer类定义中,添加一个共享的监听Socket Server成员:

#include <photon/net/socket.h>

namespace obeng {
struct ServerOptions {
    // 保持你的原有定义
    uint16_t port = 8080;
    size_t num_workers = 8;
    size_t buffer_size = 4096;
};

class HttpServer {
public:
    // 保持原有构造、router相关方法
    HttpServer(const ServerOptions& options);
    void set_router(std::unique_ptr<HttpRouter> router);
    HttpRouter& router();
    void start();

private:
    ServerOptions options_;
    std::unique_ptr<HttpRouter> router_;
    // 添加共享的监听server成员
    photon::net::ISocketServer* listen_server_ = nullptr;

    void worker_loop();
    void handle_connection(photon::net::ISocketStream* stream);
};
}

步骤2:修改start()函数,提前完成端口绑定

把创建和绑定监听Server的逻辑移到start()函数中,只执行一次,再启动worker线程:

void HttpServer::start() {
    if (!router_) {
        throw std::runtime_error("No router configured");
    }
    photon::init(photon::INIT_EVENT_DEFAULT, photon::INIT_IO_DEFAULT);
    DEFER(photon::fini());

    // 只创建并绑定一次监听Server
    listen_server_ = photon::net::new_tcp_socket_server();
    if (!listen_server_) {
        throw std::runtime_error("Failed to create TCP socket server");
    }
    DEFER(delete listen_server_);

    // 绑定端口(仅执行一次)
    if (!listen_server_->bind(options_.port)) {
        throw std::runtime_error("Failed to bind TCP server");
    }
    if (!listen_server_->listen()) {
        throw std::runtime_error("Failed to listen");
    }

    // 启动所有worker线程,共享同一个监听server
    for (size_t i = 0; i < options_.num_workers; ++i) {
        photon::thread_create11([this]() {
            this->worker_loop();
        });
    }
    photon::thread_sleep(-1);
}

步骤3:修改worker_loop(),共享监听Server

让每个worker线程直接使用已经绑定好的listen_server_去accept连接,不再重复创建server:

void HttpServer::worker_loop() {
    while (true) {
        // 使用共享的监听server接受连接
        auto* stream = listen_server_->accept();
        if (!stream) break;
        photon::thread_create11([this, stream]() {
            DEFER(delete stream);
            this->handle_connection(stream);
        });
    }
}

额外检查点

如果修改后还是有问题,可以做以下验证:

  • 确认端口真的未被占用:在Linux下可以用lsof -i :8080或ss -tulpn | grep 8080检查
  • 确认程序有足够权限绑定8080端口(1024以下端口需要root权限,但8080是非特权端口,普通用户也能绑定)

这样修改后,你的服务器应该就能正常启动并在8080端口监听了!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 11:18:08