回答UDP数据包

 危亚丽 发布于 2023-01-01 19:14

我有一个UDP服务器使用以下代码:

void initialize() 
{
    connect(&_udpSocket, SIGNAL(readyRead()), this, SLOT(onUdpDatagram()));

    _udpSocket.bind(QHostAddress::Any, 28283);
}

void onUdpDatagram()
{
    qDebug() << "udp packet received!";
    _udpSocket.write("Hello");
}

不幸的是,当收到UDP数据包时,我在日志中有以下错误:

QIODevice::write: device not open

如何使UDP套接字可写?我尝试为连接到发件人地址和端口的答案创建另一个套接字,但发送将不再使用28283端口...

任何的想法?

有关信息:我在MacOS 10.9上使用Qt 5.2.1

2 个回答
  • UDP不是基于连接的协议.您没有为每个对等体获得单独的套接字,而是在一个端口上有一个用于所有通信的套接字.

    因此,需要额外的努力来回复传入的UDP数据包.您需要从收到的数据报中检索发件人地址,然后发回相同的地址.在套接字API中,这是通过使用recvfromsendto函数而不是recv(或read)和send(或write)来完成的 - 后者是为与TCP一起使用的连接套接字而设计的.

    你没有显示你的_udpSocket变量的声明(实际上,类型),所以我假设你使用的是QUdpSocket.在这种情况下,看起来你会想要使用readDatagramwriteDatagram函数,它们recvfrom和对象sendto地址有一个额外的参数(实际上,它是一对,一个用于IP地址,一个用于端口).

    以下是Qt文档中有关的内容:

    使用此类的最常用方法是使用bind()绑定到地址和端口,然后调用writeDatagram()和readDatagram()来传输数据.如果要使用标准QIODevice函数read(),readLine(),write()等,必须首先通过调用connectToHost()将套接字直接连接到对等体.

    2023-01-01 19:16 回答
  • 巧合的是,这个警告是我在Qt上游引入的:

    QIODevice :: write:设备未打开

    它应该非常清楚,不像之前介绍的那样,即:你忘了用你的udp socket连接到主机.如果它甚至没有打开和/或连接,你不能指望它写和/或读.有关详细信息,请参阅文档

    如果要使用标准QIODevice函数read(),readLine(),write()等,必须首先通过调用connectToHost()将套接字直接连接到对等体.

    您必须在代码中的某处执行以下操作:

    _udpSocket.connectToHost(myHostAddress, 28283, ReadWrite, AnyIPProtocol);
    

    最后两个参数可以跳过,因为它们是默认值.正如您可以从文档中读到的,此方法调用也将为您打开套接字,这对于完成QIODevice读写操作是必要的.

    话虽这么说,你真的不应该忽视你的代码中的错误检查,因为它目前似乎是站立的.以这种方式找到问题将很困难.

    此外,它是冰上蛋糕,但我鼓励你开始使用"新"信号槽语法,这不是那么新,但更现代和更方便:

    void initialize() 
    {    
        connect(&_udpSocket, &QUdpSocket::connected, [&_udpSocket]() {
            connect(&_udpSocket, &QUdpSocket::readyRead, [&_udpSocket]() {
                qDebug() << "udp packet received!";
                if (_udpSocket.write("Hello") != 6)
                    qDebug() << "Failed to write:" << _udpSocket.errorString();
            });
        });
        connect(&_udpSocket, &QUdpSocket::error, [&_udpSocket]() {
            qDebug() << "Error occured:" << _udpSocket.errorString();
        });
        _udpSocket.connectToHost(myHostAddress, 28283, ReadWrite, AnyIPProtocol);
    }
    

    2023-01-01 19:18 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有