PDA

View Full Version : QUdpSocket understanding



ale301168
6th July 2011, 21:07
Hi all,

I have written a simple protocol using QUdpSocket. The protocol needs to broadcast
some data to the multicast address 239.0.0.104 - port 65000 and, at the same time,
receive data from any peers over the network which transmit to the same multicast
address and port. The sender and receiver functions are independent, that is both
functions may begin to work without any synchronism.

To implement the protocol I have used only one socket which is bound to the port
65000 and belonging to the group 239.0.0.104 to receive datagrams and, when it
needs to transmit, the socket uses the group 239.0.0.104 as destination address
and the port 65000 as destination port.

The problem I have concerns the sending of datagrams. If the sender function starts
to work before the receiver one, datagrams are not sent over the network but
only to my application since it's listening on the same port. But, if the receiver
function starts to work before the sender one, I'm able to transmit datagrams.

I have detected this behaviour using Qt 4.7.3 and a PC hosting Windows CE 5.0. If
I port the application on a PC hosting Windows XP/Vista, I have no problem sending
datagrams also if I have not still received anything.

Thank you for your cooperation

Best Regards

/Alessandro

wysota
7th July 2011, 00:34
In UDP there is no concept of "listening" on sockets so I'm not sure what you mean by this. Could we see some code responsible for socket communication?

Santosh Reddy
7th July 2011, 04:41
You need to use two QUDPSocket, one for Tx and another for Rx.

Rx UPD Socket:
- Bind to IP (Local IP) and Port (65000)
- Connect to data ready signal and read the data

Tx UPD Socket:
- Dot not bind (not required to send)
- Just send data to IP (239.0.0.104) and Port (65000)

ale301168
7th July 2011, 07:24
Here is the code I'm using:


lOldFlags = 0;

/*
** Forever loop
*/
for (;;)
{
msleep (100);

/*
** Process any datagrams in the queue
*/
while (cSocket.hasPendingDatagrams ())
{
lDgram.resize (cSocket.pendingDatagramSize ());
cSocket.readDatagram (lDgram.data (), lDgram.size (), &lPeer, &lPort);

/* ... process the datagram ... */
}


/*
** Check for unplugged network cable. When the network cable is
** unplugged and plugged again the socket stops receiving datagrams.
** The following code detects the event and calls "bind". This is the
** point where the socket is bound the first time because lOldFlags is
** initialize to zero
*/
QNetworkInterface lIf (QNetworkInterface::interfaceFromName (cAdapterName));
if (lOldFlags != lIf.flags ()) /* ... if there has been any change in the interface status ... */
{
lOldFlags = lIf.flags ();
if (lIf.flags () & 0x02) /* ... if the interface is running ... */
{
cSocket.disconnectFromHost ();
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
if (!cSocket.bind (QHostAddress ("0.0.0.0"), 65000, QUdpSocket::ReuseAddressHint))
#else
if (!cSocket.bind (QHostAddress ("0.0.0.0"), 65000, QUdpSocket::ShareAddress))
#endif
lOldFlags = 0;
else
{
int lTTL = 1;
ip_mreq lMReq;
memset ((void *) &lMReq, 0, sizeof (lMReq));
lMReq.imr_multiaddr.s_addr = _HTONL (QHostAddress ("239.0.0.104").toIPv4Address ());
lMReq.imr_interface.s_addr = _HTONL (QHostAddress ("0.0.0.0").toIPv4Address ());
if (setsockopt (cSocket.socketDescriptor (), IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *) &lMReq, sizeof (lMReq)) < 0) lOldFlags = 0;
if (setsockopt (cSocket.socketDescriptor (), IPPROTO_IP, IP_MULTICAST_TTL, (const char *) &lTTL, sizeof (lTTL)) < 0) lOldFlags = 0;
}
}
}


/*
** If there are the conditions write a datagram ...
*/
/* ... some code here to detect the conditions ... */
cSocket.writeDatagram (lMsg.data (), lMsg.size (), QHostAddress ("239.0.0.104"), 65000);

} /* end forevere loop */

wysota
7th July 2011, 07:33
You have to get rid of the forever loop, you are blocking events and thus network traffic can't be processed by Qt and you won't be getting any datagrams. I'm suprised you are getting any datagrams at all.