Qt World Summit: Submit your Presentation

[Solved] Need some enlightening: Linux sockets

  • Hi

    I have a an application written in C (which is running as sort of a deamon) that is talking (bidirectional) to a Qt application by using a local socket. This works as supposed, but I don't understand why it works the way it does. This is only partially a Qt question, it's more general socket programming in Linux. However, maybe someone can shed some light on it for me.

    The C app creates a socket on port x (AF_INET, SOCK_DGRAM, SO_REUSEADDR, INADDR_ANY) and starts polling with pollfd for event POLLIN. The C app now waits for commands/requests from the Qt app.

    Now the Qt app is started. Because the communication must be bidirectional it also creates a socket and tries to bind it to the same port (QUdpSocket, QHostAddress::LocalHost, port x, (QUdpSocket::BindMode) 0x05).
    This returns an error and can not bind. If I use a different port y, then it works, and this is how I implemented it now to have it running.

    First question: Why can I not bind to the same port? AFAIK, ports can be used bidirectional and using SO_REUSEADDR and BindMode 0x05 in Qt should allow this.

    OK, so now we have the C app listening on port x and the Qt app listening on port y.
    Now the Qt app sends something to the C app using writeDatagram (QHostAddress::LocalHost, port x).
    The C app does receive it and reports port y as the sourceport (written to the sockaddr struct upon reception). Of course, I use this port y to send back to the Qt app because the Qt app is bound to port y.

    Second question: Why does Qt send on port y which it is bound to even if using port x in writeDatagram?

    My communication between these two application works perfect if I use a separate port for each direction (I have ot because Qt does not let me bind to the same port. However, I just want to understand what is happening here. Maybe I just did understand something regarding sockets completely wrong ?!?

    Thanks for any inputs.

  • Think of a UDP socket as a mailbox. You can put a properly addressed letter into your mailbox, a mailman will pick it up and it will later be put into the receiver's mailbox. Likewise, incoming mail will appear in your mailbox. Each participant has his own mailbox (~ socket), and an address is given by the IP address (~ house number) and port (~ apartment). SO_REUSEADDR lets two or more unrelated people use the same mailbox, a horrible idea.

  • On second thought, you're right. If two (local) applications would listen on the same port, the sender would also receive his looped back protocol. That may be the reason why it does not let me bind to a port # already locally used when working with SOCK_DGRAM (UDP).
    Conclusion: local sockets always need 2 ports if bidirectional, one for each direction.

Log in to reply