2014-01-20 106 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()事件。