Results 1 to 17 of 17

Thread: QUdpSocket: sending and receiving on the same socket?

  1. #1
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default QUdpSocket: sending and receiving on the same socket?

    Hi,

    I'm trying to implement a command client / command server architecture using QUdpSocket. So far I can send QStrings and the server gets them, but when I try to send status responses back nothing happens.

    So when I send the command: "HADRONCOLLIDER5 GENERATE_STRANGELETS AMOUNT=DELUGE"

    I'd like to get back: "0 0 0 GENERATE_STRANGELETS AMOUNT=DELUGE EXTREME_DANGER".

    But I never get that return string.

    Can I send the commands to the server and read responses from the server over the same port? Or is this crazy?

    The command client is waiting for a readyRead() signal from the QUdpSocket.

  2. #2
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUdpSocket: sending and receiving on the same socket?

    Ah ha.

    I forgot that if you are *receiving* data, you have to bind to the port.

    I added the .bind() and everything seems to be working.

    Except one of our buildings seems to be turning into strange matter.

  3. #3
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUdpSocket: sending and receiving on the same socket?

    Oops, it isn't working after all.

    I thought I was getting a response, but what I was actually getting was the command I was sending the first time.

    In other words, if I'm listening for a command when I send it, I get the command that I send. Is there anyway around this?

    I tried disconnecting the readyRead() signal and reconnecting immediately after I send it, but it doesn't seem to fix it.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QUdpSocket: sending and receiving on the same socket?

    How exactly do you send the datagrams? And to what address?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. The following user says thank you to wysota for this useful post:

    mhoover (9th June 2009)

  6. #5
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUdpSocket: sending and receiving on the same socket?

    I've tried sending the datagrams a couple ways.

    1) From a class that is waiting for a readReady() response, but if it was the first one to bind to the port it catches its own response. If it was the second class to bind to the port, it sends the command, but it cannot get the response. Sounds like a turf war.

    2) From a class that sends udpSocket.write() and then immediately calls a waitForReadyRead() but never gets the response. Again, depending on whether the server binds first, it either sends the command and gets no response or the response fails to reach the server.

    For the bind() I am using QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint. For the datastreams I am using QIODevice::ReadWrite.

  7. #6
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUdpSocket: sending and receiving on the same socket?

    It would be nice if there were a udp "echo" example.


    I have seen this one (not using Qt classes):

    http://gnosis.cx/publish/programming/sockets2.html

    And this Qt example, but I haven't been able to find all the code:

    http://www.archivum.info/qt-interest.../msg00367.html

  8. #7
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUdpSocket: sending and receiving on the same socket?

    Dang, I've tried using the QAbstractSockets and that doesn't help either.

    I was thinking that if I avoided a 'bind' neither side would lock the readyRead() signals all for itself.

  9. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QUdpSocket: sending and receiving on the same socket?

    Can we see your actual code?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  10. #9
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUdpSocket: sending and receiving on the same socket?

    I realize this is not the best way to structure the code. I should use returns instead of nesting the if's more. I've been in kind of a hurry.

    client side:
    Qt Code:
    1. QUdpSocket udpSocket;
    2. QByteArray datagram;
    3. QDataStream out( &datagram, QIODevice::ReadWrite );
    4. out.setVersion( QDataStream::Qt_4_5 );
    5. out << ui.command_lineEdit->text();
    6. udpSocket.connectToHost( QHostAddress::LocalHost, 5825 );
    7. cout << "sending manual command: " << ui.command_lineEdit->text().toAscii().data() << endl;
    8. bool result = udpSocket.waitForConnected( 3000 );
    9. if ( result != false ) {
    10. qint64 writtenSize = udpSocket.write( datagram ); // send command
    11. if ( writtenSize != -1 ) {
    12. result = udpSocket.waitForReadyRead( 3000 );
    13. if ( result != false ) {
    14. cout << "found a response." << endl;
    15. while ( udpSocket.hasPendingDatagrams() ) {
    16. QByteArray datagram(command_socket_device.bytesAvailable(), '0' );
    17. command_socket_device.readDatagram(datagram.data(), datagram.size());
    18. QString the_return;
    19.  
    20. QDataStream in( &datagram, QIODevice::ReadWrite);
    21. in.setVersion( QDataStream::Qt_4_5 );
    22. in >> the_return;
    23. this->statusBar()->showMessage( the_return );
    24.  
    25. }
    26. } else {
    27. cout << "No response." << endl;
    28. }
    29. }
    30. }
    To copy to clipboard, switch view to plain text mode 

    server side:
    (called in the constructuor after a 1 sec delay)
    Qt Code:
    1. while ( !done ) {
    2.  
    3. if ( command_socket_device.hasPendingDatagrams() == true ) {
    4. cout << "found something to read." << endl;
    5. QString command( "" );
    6.  
    7. QByteArray datagram(command_socket_device.bytesAvailable(), '0' );
    8.  
    9. command_socket_device.read(datagram.data(), datagram.size());
    10.  
    11. QDataStream in( &datagram, QIODevice::ReadWrite);
    12. in.setVersion( QDataStream::Qt_4_5 );
    13. in >> command;
    14.  
    15. cout << "Received: " << command.toAscii().data() << endl;
    16. ui.log_textEdit->append( command );
    17.  
    18. if ( command == "HADRON_STARTUP" ) {
    19. command.prepend( "0 0 0 " );
    20. QByteArray datagram2;
    21. QDataStream out( &datagram2, QIODevice::ReadWrite );
    22. out.setVersion( QDataStream::Qt_4_5 );
    23. out << command;
    24. cout << "sending response: " << command.toAscii().data() << endl;
    25. command_socket_device.write( datagram2 );
    26. ui.log_textEdit->append( command );
    27. }
    28. cout << "Should have logged something." << endl;
    29. }
    30. qApp->processEvents();
    31. }
    To copy to clipboard, switch view to plain text mode 

    I've tried a lot of combinations binding and not binding to the port.

    Also, this is the blocking version I tried. I've also tried a version based on the more normal "readyRead".

  11. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QUdpSocket: sending and receiving on the same socket?

    What if you don't call connectToHost()?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  12. The following user says thank you to wysota for this useful post:

    mhoover (9th June 2009)

  13. #11
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUdpSocket: sending and receiving on the same socket?

    If I don't call connectToHost() on the server side, the client still catches it's own datagrams (regardless of which comes up first -client or server).

    If I don't call connectToHost() on the client side, the server never gets the datagram (regardless of which comes up first).

    If I don't call connectToHost() on either client or server, the server never receives the messages and the client doesn't get a response (regardless of which comes up first).

    No bind() calls were made in these classes either.

  14. #12
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUdpSocket: sending and receiving on the same socket?

    I get the sense that Qt doesn't really have much support for QUdpSockets binding to the same address. Just binding to the same port fails on Windows. See here:

    http://www.qtsoftware.com/developer/...ntry&id=216193

    It looks like the developers rejected this request because it's 'supposed' to fail.

    Which seems strange because 1) the API has an explicit 'share address' flag and 2) this gets done in UDP socket programming a lot.

  15. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QUdpSocket: sending and receiving on the same socket?

    Binding two sockets to the same port is different than using one socket for reading and writing. The latter should work fine and Qt has no chance of breaking it so I suppose you are doing something wrong. The former should fail and so it does.

    Try to replace your read() and write() calls with readDatagram() and writeDatagram().
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  16. The following user says thank you to wysota for this useful post:

    mhoover (9th June 2009)

  17. #14
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUdpSocket: sending and receiving on the same socket?

    Binding two sockets to the same port is different than using one socket for reading and writing.
    Yes, that is true.

    I saw the code fragment of a Qt UDP echo server, and I thought that meant Qt could facilitate two agents writing (at different times) to the same port. Now it looks like that is not the case.

    I tried readDatagram/writeDatagram first. I can't readDatagram without binding, and if I bind, no other agent can read it.

    My plan is to use two Udp ports: one to send the command, and one for a return status.

    Thanks for your help, wysota.

  18. #15
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QUdpSocket: sending and receiving on the same socket?

    Quote Originally Posted by mhoover View Post
    I can't readDatagram without binding, (...)
    Why so? It is meant to be used without binding.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  19. The following user says thank you to wysota for this useful post:

    mhoover (17th June 2009)

  20. #16
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUdpSocket: sending and receiving on the same socket?

    Why so? It is meant to be used without binding.
    Ahh ... connectToHost works for reading from the client side.

    Thanks.

  21. #17
    Join Date
    Jan 2006
    Location
    Maui, Hawaii
    Posts
    120
    Thanks
    65
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUdpSocket: sending and receiving on the same socket?

    I finally got this to work. My whole approach was mistaken.

    I tend to disregard parameters in Qt functions the further along I get to the right of the parameter list. This is probably a bad practice.

    Apparently when you call sendDatagram() (or readDatagram()) you can get the port number of the other socket.

    So to do a simple echo server, I just had a server bind to a port. When it got readyReads from the client it captured the port and host on the stack and then resent the information to the client.

    Meanwhile I had the client waiting on a readReady() so it could catch the response. Another thing that worked for me was to have a convenience blocking send function that used 'socket->waitForReadyRead( 3000 )' and then did a while loop on socket->hasPendingDatagrams().

    I still think it would help a lot for the Qt folks to put a Udp echo server/client example in their network examples.

    It turned out to be pretty simple, though.

    Like Columbus' egg.
    Last edited by mhoover; 17th June 2009 at 03:29. Reason: bad grammar

Similar Threads

  1. question about socket and threads?
    By oob2 in forum Qt Programming
    Replies: 2
    Last Post: 27th February 2007, 11:42
  2. qt network performance
    By criss in forum Qt Programming
    Replies: 16
    Last Post: 24th July 2006, 09:23

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.