QUdpSocket收不到回复及分析

QT中使用QUdpSocket发送数据给服务器,然后通过readyread信号读取回复。

init:
udp=new QUDPSocket()
connect(udp,SIGNAL(readyread()),this,SLOT(processread()));

work:
udp->writedatagram

实际情况是:数据能够发送出去,服务器返回的数据却无法触发readyread信号。

实验后,如下代码能够正常接收

init:
udp=new QUDPSocket()
connect(udp,SIGNAL(readyread()),this,SLOT(processread()));
udp->connectToHost()

work:
udp->write

或者

init:
udp=new QUDPSocket()
connect(udp,SIGNAL(readyread()),this,SLOT(processread()));
udp->bind()

work:
udp->writeDataGram

按照帮助文档,The most common way to use this class is to bind to an address and port using bind(), then call writeDatagram() and readDatagram() to transfer data. If you just want to send datagrams, you don’t need to call bind().
也就是说一般需要绑定,若只是发送数据不需要接收,则可以不绑定。

分析源码:
QT的编码风格是,每个可导出的类都有一个隐藏的实现类,例如QUDPSocket有一个实现类QUDPSocketPrivate,大部分的代码逻辑都是在隐藏类中实现的。
QUDPSocket继承关系:QUDPSocket->QAbstractSocket->QIODevice,QAbstractSocketEngineReceiver
QUDPSocketPrivate继承关系:QUDPSocketPrivate->QAbstractSocketPrivate->QIODevicePrivate,QAbstractSocketEngineReceiver.

其中QAbstractSocketPrivate中有一个重要的元素,QAbstractSocketEngine engine,不同的平台有不同的实现,例如linux平台实现类为QNativeSocketEngine_unix。 engine实现的逻辑就是调用像connect, send, recv这样标准的socket编程接口。

QNativeSocketEngine中保存了一个QReadNotify成员(继承QSocketNofity)

void QNativeSocketEngine::setReadNotificationEnabled(bool enable)
{
    ...
    d->readNotifier=new QReadNotifier(d->socketDescriptor,this);
    ...
}

QReadNotifier继承QSocketNotifier检车SockAct事件(QWriteNotifier和QExceptionNotifier类似)

bool QReadNotifier::event(QEvent* e)
{
    if(e->type()==QEvent::SockAct){
            engine->readNofication();
    }
    return QSocketNotifier::event(e);
}

readNotification会告知QSocketEngineReceiver

void QAbstractSocketEngine::readNotification()
{
    receiver->readNotification();
}

其中receiver是QSocketEngineReceiver类型,在QAbstractSocketEngine构造函数中被告知。readNotification是一个虚函数,在QAbstractSocketPrivate中定义,所以,实际上调用的是:

QAstractSocketPrivate::canReadNotification()
{
    ...
    emit q->readyRead();
    ...
}

q指向的QAbstractSocket导出类对象

为什么bind会影响数据的接收?
原因在于bind开启了ReadNotification

bool QUdpSocket::bind(..)
{
    ...
    d_func()->socketEngine->setReadNotificationEnabled(true);
    ...
}
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值