QUdpSocket收不到回复及分析
2016-03-09 16:09
417 查看
QT中使用QUdpSocket发送数据给服务器,然后通过readyread信号读取回复。
实际情况是:数据能够发送出去,服务器返回的数据却无法触发readyread信号。
实验后,如下代码能够正常接收
或者
按照帮助文档,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)
QReadNotifier继承QSocketNotifier检车SockAct事件(QWriteNotifier和QExceptionNotifier类似)
readNotification会告知QSocketEngineReceiver
其中receiver是QSocketEngineReceiver类型,在QAbstractSocketEngine构造函数中被告知。readNotification是一个虚函数,在QAbstractSocketPrivate中定义,所以,实际上调用的是:
q指向的QAbstractSocket导出类对象
为什么bind会影响数据的接收?
原因在于bind开启了ReadNotification
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); ... }
相关文章推荐
- QT学习 第一章:基本对话框
- 使用Shiboken为C++和Qt库创建Python绑定
- Qt 5.6更新至RC版,最终版本近在咫尺
- Qt定时器和随机数详解
- Qt实现图片移动实例(图文教程)
- Qt for Android开发实例教程
- QModelIndex/Role/Model介紹<二>
- 基于PyQt5的快速开发框架QFramer
- OSX下安装PyQt
- ok6410开发板移植DirectFB手记
- 【笔记】给Qt内嵌一个Chrome吧
- 【算法】最短路径之A*搜索
- qt入门必备
- 在 Qt4 中使用 C++11
- Hello Word ~ v0.2.2 背单词软件发布 -- By WHYPRO
- ubuntu下opencv和qt的安装配置
- linux下opengl的安装(with qt)
- qt 学习小节
- QT编译时Cannot find -lGL
- QT的命名风格