Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[Solved] QUdpSocket binding issue



  • I have been using Qt for desktop applications programming for a quite long time, but I am totally a newbie in network programmings. Recently I am developing a program to remotely control my Sony camera via WIFI.

    According to the official API document, I need to use SSDP to discover the camera and get the LOCATION, which is an address where API commands sent. I use a QUdpSocket object to send SSDP request, but I never got complete reply from the server. This problem has puzzled me for a couple of days. Fortunately, finally I fixed it by myself. I post it here. Hope someone who are also as newbie as I know how to do when encountering the same problem. Below is the description:

    My first attempt is this:

    QHostAddress hostAddress = QHostAddress("239.255.255.250");
    int SSDP_HOST = 1900;
    QUdpSocket *udpSocket = new QUdpSocket(this);
    udpSocket->bind(hostAddress, SSDP_PORT);
    udpSocket->joinMulticastGroup(hostAddress);
    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
    

    By doing this way, I will never get complete reply from the host. Like this:

    SSDP request M-SEARCH * HTTP/1.1
    HOST: 239.255.255.250:1900
    MAN: "ssdp:discover"
    MX: 1
    ST: urn:schemas-sony-com:service:ScalarWebAPI:1

    At the beginning, I totally have no idea how to debug. I thought I missed some step to setup the network configuration, but actually it was not. Then I looked the example provided in the help document, and found in the example code, the udpSocket did not bind to the host address. So I revised my code as this:

    QHostAddress hostAddress = QHostAddress("239.255.255.250");
    int SSDP_HOST = 1900;
    QUdpSocket *udpSocket = new QUdpSocket(this);
    udpSocket->bind(QHostAddress::AnyIPv4, SSDP, QUdpSocket::SharedAddress);
    udpSocket->joinMulticastGroup(hostAddress);
    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
    

    Then I got full response from the server (camera):
    NOTIFY * HTTP/1.1
    HOST: 239.255.255.250:1900
    CACHE-CONTROL: max-age=1800
    LOCATION: http://192.168.122.1:61000/scalarwebapi_dd.xml
    NT: upnp:rootdevice
    NTS: ssdp:alive
    SERVER: FedoraCore/2 UPnP/1.0 MINT-X/1.8.1
    USN: uuid:000000001000-1010-8000-B272BF6D76E5::upnp:rootdevice

    In conclusion, the lesson learned from this is this: If you want to use the same QUdpSocket object to send and receive UDP datagram to the client and from the server, you need to bind the QUdpSocket object to a different IP address, but the same port of the server's. Otherwise, you cannot get full reply.

    Hope this could help others. Thanks.


Log in to reply