问题描述
我正在尝试使用 QUdpSocket
将一些数据发送到明确定义的 host:port 目的地。当目标端口没有被监听时(例如客户端没有运行),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,[]{qDebug() << "disconnected";});
connect(&socket,&QUdpSocket::hostFound,[]{qDebug() << "hostFound";});
connect(&socket,qOverload<QUdpSocket::SocketError>(&QUdpSocket::error),&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 中看到了“无法访问端口”的 ICMP 消息。我如何才能真正接收和处理它们?
我发现在 Linux 套接字 API 中,write(2) 系统调用在这种情况下返回 -1 和 errno=ECONNREFUSED
。但是对于 QUdpSocket
,我想获得一个跨平台的解决方案。我还发现 syscall-set errno
似乎在 QUdpSocket::write()
返回后被保留,所以我可以使用它,但这是特定于 Linux 的,而我的目标平台列表还包括 Windows。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)