[Qt-interest] QUdpSocket : does not receive packets unless it sends first

John McClurkin jwm at nei.nih.gov
Mon Jan 12 19:16:25 CET 2009


wim.delvaux at adaptiveplanet.com wrote:
> Hi all,
> 
> I have done something like this :
> 
> Socket = new QUdpSocket();
> 
> Socket->bind( SomePort );
> 
> connect( Socket, SIGNAL(readyRead()), ... )
> 
> Now I have a device on the network that sends UDP packets to my IP and the 
> port I bound to (i can see the packets in wireshare).
> 
> However I never get a readyReady signal.
> 
> When I do :
> 
> Socket->writeDatagram( .... )
> 
> to the device and the device replies (using the same IP and Port) I 'DO'
> get a readyRead with the device's response.
> 
> What might be wrong ?
> 
> Thx
> W
I don't know if this will help, but here is some code I use to receive 
binary data via UDP from a sender. I aplogize for the word wrapping. 
Also, I'm not including the function rexIn() referenced in recvFromSpot 
because it is a huge switch table (I know, bad programmer, bad, bad), 
but it does not always return true, so recvFromSpot does not always send 
a datagram to the sending program. However, recvFromSpot always gets the 
data sent.

rexComm::rexComm(char *host, QObject *parent) : QObject(parent)
{

	spotSock = (QUdpSocket *)NULL;

	QHostInfo rexHost = QHostInfo::fromName(QString(host));
	if(rexHost.addresses().isEmpty() == false) {
		peerAddr = rexHost.addresses().first();
	}
	else {
		QString errmsg;
		QTextStream errStrm(&errmsg);
		errStrm << "Fatal error: can't get IP address for host " << host;
		QMessageBox::critical((QWidget *)NULL, "Host Name Error",
							  errmsg,
							  QMessageBox::Abort,
							  QMessageBox::NoButton,
							  QMessageBox::NoButton);
		exitVex(-1);
	}

	// allocate a UDP socket to receive input from spot files
	spotSock = new QUdpSocket((QObject *)this);

	// bind the socket to the port used by spot files
	spotPort = QString(GLVEX_PORT_STR).toUInt();
	if(spotSock->bind(spotPort) == false) {
		abortVex(peerAddr, spotPort);
	}
	connect(spotSock, SIGNAL(readyRead()), this, SLOT(recvFromSpot()));
}

void rexComm::recvFromSpot()
{
	uchar spotMsgRecvd[MSG_BUFFER_LEN];
	if(spotSock->hasPendingDatagrams() == true) {
		qint64 recvMsgLen = spotSock->readDatagram((char *)msgRecvd, 
MSG_BUFFER_LEN, &senderAddr, 0);

		// there was an error, set the size of the received message to zero 
and return
		if(recvMsgLen == -1) {
			qWarning("Error in reading datagram from machine at IP address %s", 
qPrintable(senderAddr.toString()));
			msgRecvd[0] = 0;
			return;
		}

		// if the message did not come from the client specified,
		// print a warning and return
		if((senderAddr == peerAddr) == false) {
			qWarning("Rejecting message from machine at IP address %s", 
qPrintable(senderAddr.toString()));
			msgRecvd[0] = 0;
			return;
		}

		// if there is a valid message from the designated host, emit a signal
		if(rexIn(msgRecvd, recvMsgLen, REX) == true) {
			quint8 signal = BATCH_DONE;			// default return signal
			spotSock->writeDatagram((char *)&signal, sizeof(signal), peerAddr, 
spotPort);
		}
	}
	
	return;
}



More information about the Qt-interest-old mailing list