c++ - 如何从 QUdpSocket 检测“端口不可达”情况?
问题描述
我正在尝试使用QUdpSocket
将一些数据发送到明确定义的主机:端口目的地。当目标端口没有被监听时(例如客户端没有运行),ICMP 消息会显示“端口不可达”。
我想在我的程序中检测到这种情况并在它发生时采取行动。我在某处读到,如果我直接“连接”到主机而不是仅仅对我的数据报进行“即发即弃”,那么应用程序应该会收到这些 ICMP 通知。但以下代码似乎没有出现任何错误。
#include <QTimer>
#include <QString>
#include <QUdpSocket>
#include <QCoreApplication>
class DataSender : public QObject
{
public:
DataSender(const QString& host, quint16 port);
void send(const char* data, unsigned size);
private:
void onSocketError(QUdpSocket::SocketError error);
private:
QUdpSocket socket;
};
DataSender::DataSender(const QString& host, const quint16 port)
{
connect(&socket, &QUdpSocket::connected, this, []{qDebug() << "connected";});
connect(&socket, &QUdpSocket::disconnected, this, []{qDebug() << "disconnected";});
connect(&socket, &QUdpSocket::hostFound, this, []{qDebug() << "hostFound";});
connect(&socket, qOverload<QUdpSocket::SocketError>(&QUdpSocket::error), this, &DataSender::onSocketError);
socket.connectToHost(host, port, QIODevice::WriteOnly);
qDebug() << "UDP server started";
}
void DataSender::send(const char*const data, const unsigned size)
{
socket.write(data, size);
}
void DataSender::onSocketError(const QUdpSocket::SocketError)
{
qDebug() << "UDP socket error:" << socket.errorString();
}
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
DataSender sender("127.0.0.1", 33333);
QTimer timer;
QObject::connect(&timer, &QTimer::timeout, [&sender]{ sender.send("Test", 4); });
timer.start(1000);
return app.exec();
}
在输出中我只得到
hostFound
connected
UDP server started
同时,在运行这个测试时,我确实在 Wireshark 中看到了“Port unreachable”ICMP 消息。我如何才能真正接收和处理它们?
我发现在 Linux 套接字 API 中 write(2) 系统调用errno=ECONNREFUSED
在这种情况下返回 -1。但是QUdpSocket
我想获得一个跨平台的解决方案。我还发现 syscall-set在返回errno
后似乎确实被保留了QUdpSocket::write()
,所以我也许可以使用它,但这是特定于 Linux 的,而我的目标平台列表也包括 Windows。
解决方案
推荐阅读
- python - 尝试在 django 视图生成的网页中显示图像
- python - 尝试从 BAT 文件运行使用 Webbot 的 Python3 脚本。我如何摆脱这个终端?
- ruby-on-rails - 为什么 Rails 迁移失败?
- django - 带铬的错误显示
- laravel - 如何在 Laravel 中根据外键选择 Eloquent
- javascript - 现在正在模态中访问 Js 脚本
- python - py文件转exe文件时调用sklearn失败
- assembly - 为什么编译器要重新计算另一个寄存器中已经存在的值?
- discord.py-rewrite - 'VoiceState' 对象没有属性 'voice_channel'
- android - 为什么广播接收器在重新启动时不起作用?