April 6, 2011

soroush soroush
Lab Rat
818 posts

Problem with QUdpSocket

 

Hi,

I’m trying to send and receive data to a program on local host (Robocup 2D Soccer Server Simulation program). the QUdpaSocket doesn’t bind to server when rcssserver is running, but when it’s closed, bind returns true. I also tried to connect using QAbstractSocket::connectToHost, it connects when server is running and I could send messages with write(QByteArray data) but anything is not received from server. (pendingDatagramSize() is -1 and size of QByteArray returned by readAll() is 0 )

my code is this:

  1.     QUdpSocket socket(this);
  2.     if(socket.bind(QHostAddress::LocalHost,6000)) // returns false when rcssserver in running
  3.     {
  4.         cout << "Connected";
  5.         socket.write(QByteArray("(init urmia-soccer (version 14))"));
  6.     }
  7.     else
  8.     {
  9.         cout << "error";
  10.     }

and with connect method:

  1.     socket.connectToHost(address,port,QIODevice::ReadWrite);
  2.     if( socket.state() == QAbstractSocket::ConnectedState)
  3.     {
  4.         cout << "Connection stabished" << endl ;
  5.         socket.write(QByteArray("(init teamName (version 14))")); // this works when server is running
  6.         QByteArray b = socket.readAll();
  7.         cout << b.size();  // is always 0. should be at least 256 characters
  8.         cout << "End of reading" << endl ;
  9.     }
  10.     else
  11.     {
  12.         cout << "Error";
  13.         exit(1);
  14.     }

What I am doing wrong here?

13 replies

April 6, 2011

Volker Volker
Ant Farmer
5428 posts

If you bind a QUdpSocket you are creating a server. As you have already a server running, the bind must fail because only one server can listen on specific tuple of host address and port.

Your second problem is most probably a race condition. You send your data immediately try to read. It’s very likely that there is no data available yet! You must connect signal readyRead of you socket to a slot. See the docs of QUdpSocket [doc.qt.nokia.com] for an example.

April 7, 2011

soroush soroush
Lab Rat
818 posts

I changed code to this. But there is no response from server. processData() is never called. but after sending (sense_body) server should return sensor data.

  1. Connection::Connection(QObject *parent) :
  2.     QObject(parent)
  3. {
  4.     socket.connectToHost(QHostAddress::LocalHost,6000);
  5.     if(socket.state() == QAbstractSocket::ConnectedState)
  6.     {
  7.         cout << "connection stabished";
  8.         connect(&socket,SIGNAL(readyRead()),this, SLOT(processData()));
  9.         socket.write("(init team-name (version 14));");
  10.         socket.write("(sense_body)");
  11.         // cout << socket.readAll().size(); // if called here, returns 0
  12.     }
  13.     else
  14.     {
  15.         cout << "connection failed";
  16.     }
  17. }
  18.  
  19. void Connection::processData()
  20. {
  21.     cout << socket.readAll().size(); // is never called.
  22. }

April 7, 2011

Volker Volker
Ant Farmer
5428 posts

There is no connect() statement that connects a signal to your slot.
(sorry, looked in the wrong place)

April 7, 2011

soroush soroush
Lab Rat
818 posts

Thanks for your reply,

I tried debuging and found that server emits player disconnection messages immediately after running this line:

  1. socket.write("(init team-name (version 14))");

but calling socket.state() returns QAbstractSocket::ConnectedState even after server says player is disconnected. Naturally anything is not returned to client when server thinks player is disconnected….

I think there is a problem with server. that is written in c and c++ completely. it works fine with its own client (rcssclient).

Any ideas?

April 7, 2011

Andre Andre
Robot Herder
6399 posts

Well, we obviously don’t know the protocol used by your server, so it is hard to go into that. My cat shattered my last crystal ball, you know…

What is funny in this, is that you’re talking about connecting and disconnecting in the context of UDP. UDP is a connectionless protocol. It just sends datagrams, and does not guarantee that they arrive or arrive in order. There is no concept of a connection (like TCP does offer) in UDP.

April 7, 2011

soroush soroush
Lab Rat
818 posts

So,… why server says:

  1. ...
  2. A player disconnected : (team-name 1)
  3. ...

when I send initialization message? I’m completely confused. :-/

April 7, 2011

Andre Andre
Robot Herder
6399 posts

How should we know why your server would say that? We have no access to that server or what it does! Perhaps ask the maintainer of that service why it behaves the way it does?

April 7, 2011

Volker Volker
Ant Farmer
5428 posts
Andre wrote:
What is funny in this, is that you’re talking about connecting and disconnecting in the context of UDP. UDP is a connectionless protocol. It just sends datagrams, and does not guarantee that they arrive or arrive in order. There is no concept of a connection (like TCP does offer) in UDP.

I think it’s to certain degree because of this paragraph in QUdpSocket docs [doc.qt.nokia.com]”:

The most common way to use this class is to bind to an address and port using bind(), then call writeDatagram() and readDatagram() to transfer data. If you want to use the standard QIODevice functions read(), readLine(), write(), etc., you must first connect the socket directly to a peer by calling connectToHost().
[Highlighting by me]

April 7, 2011

Andre Andre
Robot Herder
6399 posts

That might be it yes. The Qt API is a bit weird in this point.

April 7, 2011

Volker Volker
Ant Farmer
5428 posts
Andre wrote:
That might be it yes. The Qt API is a bit weird in this point.

Once we have the new stuff [developer.qt.nokia.com] DevNet we can add a big warning :-)

April 7, 2011

Andre Andre
Robot Herder
6399 posts

Yep. Already have some places in mind where I’d like to add some thoughts…

April 7, 2011

peppe peppe
Ant Farmer
1028 posts
Andre wrote:
That might be it yes. The Qt API is a bit weird in this point.

It’s not weird. For decades UNIX has supported connect(2)ing UDP sockets, with well-definite semantics. Qt simply does the same thing.

 Signature 

Software Engineer
KDAB (UK) Ltd., a KDAB Group company

April 7, 2011

Andre Andre
Robot Herder
6399 posts

The group of people working with Qt is obviously broader than well-versed unix programmers. I find it weird to talk about connections when you are dealing with a protocol that does not handle connections. I looked it up what it does in Unix. It seems that it does two things:

  1. set a default host address where data packages are send to
  2. limit receiving datagrams to only those from the host you “connected” to.

The QUdpSocket documentation mentions neither, but seems to do something like 1) at least. What’s more, it first states that UDP is connectionless, and then in the next paragraph, explains that you need to connect to use certain methods. Excuse me, but I find that weird and inconsistent, no matter what older Unix API may use the same kind of terminology.

 
  ‹‹ Autosizing scrollable window      [closed] adding another column to QFileSystemModel ››

You must log in to post a reply. Not a member yet? Register here!