2014-01-20 74 views
2

我有问题要找出为什么我的短QUdpSocket示例不起作用。我计划只使用一个UDP套接字在端口2007上以192.168.2.66读取和写入嵌入式设备。设备将始终在端口2007上回复发件人。我使用UDP终端软件测试了设备,并按照我的说法工作。所以,我设计了一个简单的类嵌入到管理设备所需要的功能:Qt QUdpSocket:readyRead()信号和相应的插槽不能正常工作

class QUdp : public QObject 
{ 
    // Q_OBJECT 
public: 
    explicit QUdp(QObject *parent = 0, const char *szHost = 0, uint16_t wPort = 0); 
    ~QUdp(); 
    bool Open(); 
    int64_t Write(QByteArray &data); 
    int64_t Write(QString strData); 
private: 
    QString m_strHost; 
    uint16_t m_wPort; 
    QUdpSocket *OUdp; 
private slots: 
    void received(); 
}; 

我想,这个问题是在打开方法:

bool QUdp::Open() 
{ 
    QHostAddress OHost; 
    connect(OUdp, &QUdpSocket::readyRead, this, &QUdp::received); 
    bool zRet = OUdp->bind(QHostAddress::AnyIPv4, m_wPort, QUdpSocket::ShareAddress); 
    OHost.setAddress(m_strHost); 
    OUdp->connectToHost(OHost, m_wPort, QIODevice::ReadWrite); 
    return(zRet); 
} 
//------------------------------------------------------------------------ 

我使用了Qt 5语法用于连接(),m_strHost值是“192.168.2.66”和m_wPort是2007

我写的方法很简单(加入内0#如果部分,看看如果套接字接收到的数据)

int64_t QUdp::Write(QString strData) 
{ 
    QByteArray data(strData.toStdString().c_str(), strData.length()); 
    int64_t iCount = OUdp->write(data); 
#if 0 
    bool zRecved = OUdp->waitForReadyRead(3000); 
    int64_t iRecvCount = OUdp->bytesAvailable(); 
#endif 
    return(iCount); 
} 
//------------------------------------------------------------------------ 

,这是我收到的测试()方法......我写它只是为了看看信号槽工程或不:

void QUdp::received() 
{ 
    int64_t iRecvCount = OUdp->bytesAvailable(); 
} 
//------------------------------------------------------------------------ 

我不明白什么是错的。我发现有些帖子说这是不可能的,只能在Qt中使用一个UDP套接字来读写(Qt使用BSD套接字,所以它应该是可能的),但我的例子看起来是建议的解决方案,所以我真的不明白什么是不工作的。

回答

2

你可以在Qt中使用一个UDP套接字来读写。我已经在这个运行QT5在Windows和Linux,所以不用担心有:)

建立的Rx直接通信在QUdpSocket提供你应该使用bind()函数,是这样的:

// Rx connection: check we are not already bound 
if (udpSocket->state() != udpSocket->BoundState) 
{ 
    // Rx not in bound state, attempt to bind 
    udpSocket->bind(address, port); 
} 

一旦完成,您将能够检查udpSocket->state() == udpSocket->BoundState是否为真,然后您成功“绑定”到此IP /端口。现在,如果您与readready()的连接正确,您可以开始聆听。我没用过,你正在使用此连接的语法,所以我不能说太多关于这一点,但这里是我如何连接的例子:

connect(udpSocket, SIGNAL(readyRead()), this, SLOT(rxDataEvent()), Qt::QueuedConnection); 

在哪里“这”是包含我QUdpSocket提供类而udpSocket是一个QUdpSocket指针。然后rxDataEvent定义如下:

void CIpComms::rxDataEvent(void) 
{ 
    QByteArray rxData; 
    QHostAddress sender; 
    quint16 senderPort; 

    while (udpSocket->hasPendingDatagrams()) 
    { 
     // Resize and zero byte buffer so we can make way for the new data. 
     rxData.fill(0, udpSocket->pendingDatagramSize()); 

     // Read data from the UDP buffer. 
     udpSocket->readDatagram(rxData.data(), 
           rxData.size(), 
           &sender, 
           &senderPort); 

     // Emit ipDataReceived Signal 
     emit ipDataReceived(rxData); 
    } 
} 

在这里,我们不断地检查数据包,直到有没有挂起(有点容易然后做整个“信息bytesAvailable事”)和数据粘成一个QByteArray中和其他地方发出其关闭(其中你明显不需要这样做!)。

这就是你需要做的连接。然后派是很容易,你只需要调用“writeDatagram()”,以及还有其他的选择,但是这是迄今为止更容易使用:

if (-1 == udpSocket->writeDatagram(txData, address, port)) 
{ 
    // Data write failed, print out warning 
    qWarning() << "Unable to write data to " << address.toString() << ":" << port << endl; 
    return false; 
} 

我有相当多切和粘贴此我工作代码(通过几个编辑来保持它简短 - 简单,所以它应该给你一个起点)总之,我认为你错了是因为你没有“绑定”到IP地址/端口,因此,不听它,不会收到任何readReady()事件。