QUdpSocket收不到回复及分析

来源:互联网 发布:js window监听事件 编辑:程序博客网 时间:2024/05/27 00:49

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);    ...}
0 0
原创粉丝点击