PDA

View Full Version : QSocketNotifier does not react to socket´s activities



evquimu
28th April 2008, 15:17
Hi,

i am programming a Qt-application which receives UDP-datagrams for other remote Qt-application. To control the activity of the socket, which is inherited from the Q3SocketDevice, i have used the class QSocketNotifier. The QSocketNotifier was defined as a Read-SocketNotifier and the necessary signal/slot are defined like in all found examples.

The problem is that the QSocketNotifier does not react to the reception of UDP-datagrams, although datagrams are definitely received, because i see them with the aid of one sniffer programm.

The programmed Qt-application works correctly without the presence of the QSocketNotifier, because the Qt-application was too programmed by the means of an extra thread or via the well-known signal/slots-process. As soon as the QSocketNotifier are declared at the constructor of the programmed class (kind class), no signal is emitted if a UDP-datagram is received.

The source code of my classes (Receiver (father class) and (Receiver class) kind class) are below. I hope, you can help me!!!!!

Thank you in advance

----------------------------------------------
main

#include "..\LTEFramework\ReceiverUDP.h"

#include <QtCore/QCoreApplication>
#include <QHostAddress>
#include <iostream>

using namespace std; // to find cout

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

cout<< "Process started.\n";

quint16 peerPort = 3000;
QHostAddress* peer_ipaddress = new QHostAddress("192.168.0.199");
ReceiverUDP* p_udp_receiver = new ReceiverUDP(2002,peer_ipaddress,peerPort);

if(p_udp_receiver->IsSocketBound())
{
bool notifier_enabled = p_udp_receiver->isSocketNotifierEnabled();
bool isMessage = p_udp_receiver->isMessageReceived();
if(isMessage)
{
cout<<"There are neu datagrams.\n";
quint64 messageCount = p_udp_receiver->getMessageCount();
cout<< "" <<messageCount<< " have been received.\n";
quint64 message_length = p_udp_receiver->getReceivedBytes();
cout<< "The received datagram has " <<message_length<< " bytes.\n";
}
else
{
cout<<"There are not received datagrams.\n";
}

}
else
{
cout<< "The data could not be received.\n";
}
cout<< "Process finished.\n";
delete p_udp_receiver;
return a.exec();
}
--------------------------------------
---------------------------------------
Receiver.h
#ifndef RECEIVER_H
#define RECEIVER_H

#include <QObject>
#include <Qt3Support/Q3SocketDevice>
#include <QtCore/QIODevice>
#include <QtCore/QSocketNotifier>
#include <QHostInfo>
#include <QtCore/QString>
#include <QHostAddress>
#include <QDateTime>
#include <iostream>

#include<stdlib.h>
using namespace std;


class Receiver : public QObject
{
Q_OBJECT

public:
Receiver(); // standard constructor;
virtual ~Receiver(); // destructor

qlonglong GetReceivedBytes;
void SetReceiveBufferSize(uint receiveBufferSize);

quint64 getMessageCount();
quint64 getReceivedBytes();
bool isSocketNotifierEnabled();
bool isMessageReceived();
virtual QHostAddress getIPAddresOfReceivedMessage()=0;
virtual quint16 getRemotePortOfReceivedMessage() = 0;
virtual double getMbitsPerSecond() = 0;
QByteArray* getBytesArrayOfReceivedMessage();

private:
quint64* plastMessageCount;
QSocketNotifier* psocketNotifier;

protected:
Q3SocketDevice* pSocketDevice; // Socket to receive datagrams which will be initialized at the kind class
QDateTime* plast_MBit_per_second_call_timeStamp;
quint64* preceivedBytes;
quint64* pmessageCount;
QByteArray* pBytesArrayOfReceivedMessage;
};

#endif // RECEIVER_H
-----------------------------
------------------------------
Receiver.cpp

#include "receiver.h"
#include <Qt3Support/Q3SocketDevice>
#include <QtCore/QIODevice>
#include <QtCore/QSocketNotifier>
#include <QHostInfo>
#include <QtCore/QString>
#include <QHostAddress>
#include <QDateTime>
#include <iostream>

#include<stdlib.h>
using namespace std;

Receiver::Receiver()
{
pSocketDevice = NULL;
plast_MBit_per_second_call_timeStamp = NULL;
preceivedBytes = NULL;
psocketNotifier = NULL;
plastMessageCount = new quint64();
pBytesArrayOfReceivedMessage = NULL;
}

Receiver::~Receiver()
{
if (pBytesArrayOfReceivedMessage)
delete pBytesArrayOfReceivedMessage;

pBytesArrayOfReceivedMessage = NULL;

delete plastMessageCount;

if (preceivedBytes)
delete preceivedBytes;

preceivedBytes = NULL;

if (pmessageCount)
delete pmessageCount;

pmessageCount = NULL;

if (plast_MBit_per_second_call_timeStamp)
delete plast_MBit_per_second_call_timeStamp;

plast_MBit_per_second_call_timeStamp= NULL;


if psocketNotifier
delete pmessageCount;

pmessageCount;= NULL;


if (pSocketDevice)
delete pSocketDevice;

pSocketDevice=NULL;
}

void Receiver::SetReceiveBufferSize(uint receiveBufferSize)
{
pSocketDevice->setReceiveBufferSize(receiveBufferSize);
if ( pSocketDevice->receiveBufferSize()!= receiveBufferSize)
{
cout<<"Error!The receive buffer size could not be set.\n";
}
}

bool Receiver::isSocketNotifierEnabled()
{
bool enabled = psocketNotifier->isEnabled();
return enabled;
}

quint64 Receiver::getReceivedBytes()
{
return *preceivedBytes;
}

quint64 Receiver::getMessageCount()
{
return *pmessageCount;
}

bool Receiver::isMessageReceived()
{
if(*pmessageCount>*plastMessageCount)
{
return true;
}
return false;

}
QByteArray* Receiver::getBytesArrayOfReceivedMessage()
{
return pBytesArrayOfReceivedMessage;
}

--------------------------

---------------------------
ReceiverUDP.h

#ifndef RECEIVERUDP_H
#define RECEIVERUDP_H

#include <QObject>
#include <QHostAddress>
#include <QDateTime>
#include <Qt3Support/Q3SocketDevice>
#include <QtCore/QSocketNotifier>
#include <iostream>
#include "..\LTEFramework\Receiver.h"

using namespace std;
class ReceiverUDP : public Receiver
{
Q_OBJECT

public:

ReceiverUDP(quint16 portToListen, QHostAddress* pRemoteIP,quint16 remotePort); // constructor
virtual ~ReceiverUDP(); // destructor

bool IsSocketBound();
double getMbitsPerSecond();
QHostAddress getIPAddresOfReceivedMessage();
quint16 getRemotePortOfReceivedMessage();
bool isSignal;

signals:

private slots:
void messageReceived();

protected:

private:
bool socket_bound;

};

#endif // RECEIVERUDP_H
-------------------------

---------------------------
ReceiverUDP.cpp

#include "Receiver.h"
#include "ReceiverUDP.h"

#include <QObject>
#include <QHostAddress>
#include <QDateTime>
#include <Qt3Support/Q3SocketDevice>
#include <QtCore/QSocketNotifier>
#include <iostream>

using namespace std;

ReceiverUDP::ReceiverUDP(quint16 portToListen, QHostAddress* pRemoteIP,quint16 remotePort):Receiver()
{
preceivedBytes = new quint64();

pmessageCount = new quint64();

this->pSocketDevice = new Q3SocketDevice(Q3SocketDevice:big grin atagram); // to define the datagram socket
this->socket_bound = pSocketDevice->bind(QHostAddress(),portToListen); // it will be accepted datagrams to the remote IP Address


if(socket_bound)
{
cout<<"The socket could be bound.\n";
pSocketDevice->setAddressReusable(true);
}
else
{
Q3SocketDevice::Error error = pSocketDevice->error();
cout<<"The error is the number "<<error<<".\n";
}

isSignal = false;
if(!socket_bound)
{
//error hier behandeln
}
else
{
this->psocketNotifier = new QSocketNotifier(pSocketDevice->socket(),QSocketNotifier::Read,this);
psocketNotifier->setEnabled(true);
int socketIdentifier = psocketNotifier->socket();
ReceiverUDP::connect(psocketNotifier,SIGNAL(activa ted(int)),SLOT(messageR
eceived()));

plast_MBit_per_second_call_timeStamp = new QDateTime(QDateTime::currentDateTime());

}
}
ReceiverUDP::~ReceiverUDP()
{
if (pBytesArrayOfReceivedMessage)
delete pBytesArrayOfReceivedMessage;

pBytesArrayOfReceivedMessage = NULL;

if (preceivedBytes)
delete preceivedBytes;

preceivedBytes = NULL;

if (pmessageCount)
delete pmessageCount;

pmessageCount = NULL;

if (plast_MBit_per_second_call_timeStamp)
delete plast_MBit_per_second_call_timeStamp;

plast_MBit_per_second_call_timeStamp= NULL;

if (psocketNotifier)
delete psocketNotifier;

psocketNotifier= NULL;

if (pSocketDevice)
delete pSocketDevice;

pSocketDevice=NULL;
}

bool ReceiverUDP::IsSocketBound()
{
return socket_bound;
}

void ReceiverUDP::messageReceived()
{
cout<<"method receive!!!!!.\n";
this->psocketNotifier->setEnabled(false);

pBytesArrayOfReceivedMessage = new QByteArray((quint64)pSocketDevice->bytesAvailable());
char* message_in_char = pBytesArrayOfReceivedMessage->data();

*preceivedBytes = pSocketDevice->readBlock(message_in_char,(qlonglong)pBytesArrayOf ReceivedMe
ssage->size()); // to read the datagram which is in the receive buffer
QDataStream in(pBytesArrayOfReceivedMessage, QIODevice::WriteOnly);
in.readRawBytes(message_in_char,(uint)pBytesArrayO fReceivedMessage->size()
);

*pmessageCount = *pmessageCount + 1;
*preceivedBytes = pBytesArrayOfReceivedMessage->size();

this->psocketNotifier->setEnabled(true);

}
double ReceiverUDP::getMbitsPerSecond()
{
int time_difference_in_secs = QDateTime::currentDateTime().secsTo(*plast_MBit_pe r_second_call_timeStamp);

double Mbitspersecond;
double numerator;
double denominator;

if(time_difference_in_secs==0)
{
Mbitspersecond=0;
}
else
{
numerator = (*preceivedBytes)*8.0/(1024.0*1024.0);
denominator = (double)(time_difference_in_secs);
Mbitspersecond =(numerator)/(denominator);

*preceivedBytes=0;
this->plast_MBit_per_second_call_timeStamp->currentDateTime();
}
return Mbitspersecond;
}

QHostAddress ReceiverUDP::getIPAddresOfReceivedMessage()
{
QHostAddress remoteIPAddress = pSocketDevice->peerAddress();
return remoteIPAddress;
}

quint16 ReceiverUDP::getRemotePortOfReceivedMessage()
{
quint16 remotePort = pSocketDevice->peerPort();
return remotePort;
}
----------------------------