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

如何在Poco C++中测量数据报套接字自上次接收消息后的耗时?

解决Poco DatagramSocket阻塞接收的超时通知问题

默认的receiveFrom()是阻塞式调用,无消息时会一直挂起,无法触发超时通知。以下提供两种可行方案:

方案一:设置套接字接收超时

通过setReceiveTimeout()给DatagramSocket设置超时时间,超时后receiveFrom()会抛出Poco::TimeoutException,捕获该异常即可触发超时逻辑。

#include <iostream>
#include <string>
#include "Poco/Net/DatagramSocket.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/TimeoutException.h"
#include "Poco/Timespan.h"

int port = 5000;

int main() {
    Poco::Net::SocketAddress sa(Poco::Net::IPAddress(), port);
    Poco::Net::DatagramSocket dgs(sa, true);
    char buffer[1024];
    Poco::Net::SocketAddress sender;

    // 设置超时时间为5秒(第一个参数为秒,第二个为微秒)
    dgs.setReceiveTimeout(Poco::Timespan(5, 0));

    for (;;) {
        try {
            int n = dgs.receiveFrom(buffer, sizeof(buffer)-1, sender);
            buffer[n] = '\0';
            std::string line = buffer;
            std::cout << "收到消息:" << line << std::endl;
            // 处理消息逻辑
        } catch (const Poco::TimeoutException&) {
            // 超时触发通知
            std::cout << "超过5秒未收到消息!" << std::endl;
        }
    }
    return 0;
}
  • Poco::Timespan支持多种时间单位构造,比如直接传入微秒值Poco::Timespan(5000000)也表示5秒。
  • 每次超时都会进入catch块,可在此添加自定义通知逻辑(如日志、告警)。

方案二:使用SocketSelector监控套接字

SocketSelector可监控套接字的可读状态,调用select()时指定超时时间,超时后返回false,即可处理无消息场景。这种方式更适合同时监控多个套接字的场景。

#include <iostream>
#include <string>
#include "Poco/Net/DatagramSocket.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/Net/SocketSelector.h"
#include "Poco/Timespan.h"

int port = 5000;

int main() {
    Poco::Net::SocketAddress sa(Poco::Net::IPAddress(), port);
    Poco::Net::DatagramSocket dgs(sa, true);
    char buffer[1024];
    Poco::Net::SocketAddress sender;
    Poco::Net::SocketSelector selector;

    selector.add(dgs);
    // 设置超时时间为5秒
    Poco::Timespan timeout(5, 0);

    for (;;) {
        // 等待套接字可读或超时
        if (selector.select(timeout)) {
            if (selector.isReadable(dgs)) {
                int n = dgs.receiveFrom(buffer, sizeof(buffer)-1, sender);
                buffer[n] = '\0';
                std::string line = buffer;
                std::cout << "收到消息:" << line << std::endl;
                // 处理消息逻辑
            }
        } else {
            // 超时触发通知
            std::cout << "超过5秒未收到消息!" << std::endl;
        }
    }
    return 0;
}
  • selector.select(timeout)会阻塞至有套接字可读或超时,返回true表示有可读数据,false表示超时。

内容的提问来源于stack exchange,提问作者Foktris 95

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:35:14