notfound404
15th August 2017, 17:15
I am trying to implement custom QIODevice.
I have detector which will be using 2 tcp sockets, one for sending commands and receiving responses, the other one just for reading data.
How should I do it? I tried to create my class, derive it from QIODevice and implement pure virtual methods, but I faced some dificulties.
I have the following piece of code:
class Detector : public QIODevice {
Q_OBJECT
Q_DISABLE_COPY(MasterDevice)
public:
enum CHANNEL_TYPE {
DataChannel,
ControlChannel
};
private:
QTcpSocket *controlDevice;
QTcpSocket *dataDevice;
QHostAddress hostAddress;
quint16 dataPort;
quint16 controlPort;
public:
explicit Detector(QObject *parent, QHostAddress hostAddress, quint16 dataPort, quint16 controlPort)
: QIODevice(parent)
, hostAddress(hostAddress)
, dataPort(dataPort)
, controlPort(controlPort)
{
controlDevice = new QTcpSocket(this);
connect(controlDevice, SIGNAL(readyRead()),this, SLOT(controlChannelReadReady()));
dataDevice = new QTcpSocket(this);
connect(dataDevice, SIGNAL(readyRead()),this, SLOT(dataChannelReadReady()));
}
virtual ~Detector() {}
bool open(OpenMode mode) override {
QIODevice::open(mode);
controlDevice->connectToHost(hostAddress, controlPort, QTcpSocket::ReadWrite);
dataDevice->connectToHost(hostAddress, dataPort, QTcpSocket::ReadOnly);
}
qint64 readData(char *data, qint64 maxSize) override {
QTcpSocket *socket;
switch ( currentReadChannel() ) {
case DataChannel:
socket = dataDevice;
break;
case ControlChannel:
socket = controlDevice;
break;
default:
return -1;
break;
}
return socket->read(data, maxSize);
}
qint64 writeData(const char * data, qint64 maxSize) override {
QTcpSocket *socket;
switch ( currentWriteChannel() ) {
case DataChannel:
socket = dataDevice;
break;
case ControlChannel:
socket = controlDevice;
break;
default:
return -1;
break;
}
return socket->write(data, maxSize);
}
private slots:
void controlChannelReadReady() {
emit channelReadyRead(ControlChannel);
}
void dataChannelReadReady() {
emit channelReadyRead(DataChannel);
}
};
So basically my question is, how do I handle those channels, because for example from qt documentation I have this
bool QIODevice::open(OpenMode mode)
Opens the device and sets its OpenMode to mode. Returns true if successful; otherwise returns false. This function should be called from any reimplementations of open() or other functions that open the device.
So I have to invoke it from my overrided Open() method, but I looked at the implementation of this method and I saw that it is setting the number of channels to 1. How can I change this number?
What for are those buffers that I am inheriting from QIODevice, how should I use them?
Am I missing the point of creating custom QIODevice? If so, please explain it to me.
I have detector which will be using 2 tcp sockets, one for sending commands and receiving responses, the other one just for reading data.
How should I do it? I tried to create my class, derive it from QIODevice and implement pure virtual methods, but I faced some dificulties.
I have the following piece of code:
class Detector : public QIODevice {
Q_OBJECT
Q_DISABLE_COPY(MasterDevice)
public:
enum CHANNEL_TYPE {
DataChannel,
ControlChannel
};
private:
QTcpSocket *controlDevice;
QTcpSocket *dataDevice;
QHostAddress hostAddress;
quint16 dataPort;
quint16 controlPort;
public:
explicit Detector(QObject *parent, QHostAddress hostAddress, quint16 dataPort, quint16 controlPort)
: QIODevice(parent)
, hostAddress(hostAddress)
, dataPort(dataPort)
, controlPort(controlPort)
{
controlDevice = new QTcpSocket(this);
connect(controlDevice, SIGNAL(readyRead()),this, SLOT(controlChannelReadReady()));
dataDevice = new QTcpSocket(this);
connect(dataDevice, SIGNAL(readyRead()),this, SLOT(dataChannelReadReady()));
}
virtual ~Detector() {}
bool open(OpenMode mode) override {
QIODevice::open(mode);
controlDevice->connectToHost(hostAddress, controlPort, QTcpSocket::ReadWrite);
dataDevice->connectToHost(hostAddress, dataPort, QTcpSocket::ReadOnly);
}
qint64 readData(char *data, qint64 maxSize) override {
QTcpSocket *socket;
switch ( currentReadChannel() ) {
case DataChannel:
socket = dataDevice;
break;
case ControlChannel:
socket = controlDevice;
break;
default:
return -1;
break;
}
return socket->read(data, maxSize);
}
qint64 writeData(const char * data, qint64 maxSize) override {
QTcpSocket *socket;
switch ( currentWriteChannel() ) {
case DataChannel:
socket = dataDevice;
break;
case ControlChannel:
socket = controlDevice;
break;
default:
return -1;
break;
}
return socket->write(data, maxSize);
}
private slots:
void controlChannelReadReady() {
emit channelReadyRead(ControlChannel);
}
void dataChannelReadReady() {
emit channelReadyRead(DataChannel);
}
};
So basically my question is, how do I handle those channels, because for example from qt documentation I have this
bool QIODevice::open(OpenMode mode)
Opens the device and sets its OpenMode to mode. Returns true if successful; otherwise returns false. This function should be called from any reimplementations of open() or other functions that open the device.
So I have to invoke it from my overrided Open() method, but I looked at the implementation of this method and I saw that it is setting the number of channels to 1. How can I change this number?
What for are those buffers that I am inheriting from QIODevice, how should I use them?
Am I missing the point of creating custom QIODevice? If so, please explain it to me.