pythonqtudppython-socketsqudpsocket

Qt Write to UDP Socket on Linux Machine and Windows Read from Socket with Python


=========== UPDATE: ===========

I am now using the broadcast ip 10.6.0.3 and a higher port, 57890. I can see the traffic in Windows Network Monitor but still cannot get Python to read it.

==============================

I have a linux machine writing a 'hello' message to a UDP socket on ip address 10.6.0.2 using Qt and QUDPSocket. I also have a Windows machine that I want to read that 'hello' message using Python. From my Qt Code, I can see that the data is being written, however, the Python program on Windows sits forever on "Waiting for data". The windows machine can indeed ping 10.6.0.2. What am I doing wrong?

Test sequence:

UdpBroadcaster client; // Binds socket
sleep(10); // During this time , startup Python program
client.WriteData(); // Write hello message

Qt Output:

Initializing UDP Socket 
Determined ip address to be:  "10.6.0.2" 
Successfully bound to:   QHostAddress( "10.6.0.2" )   Port:  5678 
Sending UDP Datagram now! 
Wrote this many bytes:  8 
Message From:  "10.6.0.2" 
With Port Number  5678 
Message:  "Hello!!!" 

Qt Code:

// Constructor
UdpBroadcaster::UdpBroadcaster(QObject *parent) :QObject(parent)

{

    // Init socket
    m_UdpSocket = new QUdpSocket(this);

    // Figure out our ip address to broadcast on
    QString ipAddress;
    foreach (const QHostAddress &address, QNetworkInterface::allAddresses()) {
        if (address.protocol() == QAbstractSocket::IPv4Protocol && address != QHostAddress(QHostAddress::LocalHost))
            if ( address.toString().contains("10.") ) {
                ipAddress = address.toString();
                qDebug() << "Determined ip address to be: " << ipAddress;
                break;
            }
    }

    // Bind to localhost
    m_Port = 5678;
    m_AddressToUse = QHostAddress(ipAddress);
    bool didBind = m_UdpSocket->bind(m_AddressToUse,m_Port);
    if ( !didBind ) {
        qDebug() << "Error! Cannot bind to: " << m_AddressToUse << " Port: " << m_Port;
    }
    else {
        qDebug() << "Successfully bound to: " << m_AddressToUse << " Port: " << m_Port;
    }

    // Connect the ready read socket
    connect(m_UdpSocket,SIGNAL(readyRead()),this,SLOT(readReady()));

}

// Write data to socket
void UdpBroadcaster::WriteData() {

    // Debug
    qDebug() << "Sending UDP Datagram now!";

    // Construct a message to send
    QByteArray msg;
    msg.append("Hello!!!");
    qint64 numberOfBytesWritten = m_UdpSocket->writeDatagram(msg,m_AddressToUse,m_Port);
    if ( numberOfBytesWritten == -1 ) {
        qDebug() << "Error! Could not write data to socket...";
    }
    else {
        qDebug() << "Wrote this many bytes: " << numberOfBytesWritten;
    }

}

// Do this when a datagram is available
void UdpBroadcaster::readReady() {

    // Buffer to receive data
    QByteArray buffer;
    buffer.resize(m_UdpSocket->pendingDatagramSize());

    QHostAddress sender;
    quint16 port;
    m_UdpSocket->readDatagram(buffer.data(),buffer.size(),&sender,&port);

    qDebug()<<"Message From: " << sender.toString();
    qDebug()<<"With Port Number " << port;
    qDebug()<<"Message: " << buffer;

}

Python Program:

import socket
import time

def main():

    UDP_IP = "10.6.0.2"
    UDP_PORT = 5678

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.connect((UDP_IP, UDP_PORT))
    cnt = 0
    while cnt < 10:
        print "Waiting for data"
        data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
        print "received message:", data
        time.sleep(1)
        cnt = cnt + 1

    ## Wait so we don't lose our terminal
    filename = raw_input()            

if __name__ == '__main__':
    main()

Solution

  • I had to allow my program through the Windows 7 Firewall . Now it works fine.