私はの上に独自のラッパーを実装しようとしています。その理由はuncomfortable to useです。私はそれを使用することができますが、とにかく私は、QDataStream操作へのアクセスのためにいくつかの中間バッファを実装する必要があります。追加的に:サブクラスQIODevice:QUdpSocketのラッパー
Iはsublass QIODevice、
ヘッダ(ビット簡体字):
class BerUdp : public QIODevice
{
Q_OBJECT
void startup();
public:
void setHostToWrite(const QHostAddress &address, quint16 port);
void setPortToRead(quint16 port);
qint64 bytesAvailable() const;
protected: // Reimplement:
qint64 readData(char *data, qint64 maxSize);
qint64 writeData(const char *data, qint64 maxSize);
private:
QUdpSocket* dev_write; // udp socket to write
QUdpSocket* dev_read; // udp socket to read
QBuffer m_buffer; // buffer to store received datagrams
};
.cppファイル:のQt documuntationから
void BerUdp::startup()
{
m_buffer.open(QIODevice::ReadWrite);
open(QIODevice::ReadWrite);
}
void BerUdp::setHostToWrite(const QHostAddress &address, quint16 port)
{
dev_write->connectToHost(address, port);
dev_write->waitForConnected();
}
void BerUdp::setPortToRead(quint16 port)
{
dev_read->bind(port);
dev_read->open(QIODevice::ReadOnly);
bool ok = connect(dev_read, &QIODevice::readyRead,
this, &BerUdp::onReceive);
}
// Read new received data to my internal buffer
void BerUdp::onReceive()
{
bool av = dev_read->hasPendingDatagrams();
if (av)
{
int dSize = dev_read->pendingDatagramSize();
QByteArray dtg(dSize, 0);
dev_read->readDatagram(dtg.data(), dtg.size());
// write new data to the end
int buf_read_pos = m_buffer.pos();
m_buffer.seek(m_buffer.size());
m_buffer.write(dtg);
m_buffer.seek(buf_read_pos);
}
}
QIODevice::readData()オン
..この関数を再実装するときは、この関数 が返す前にすべての必要なデータを読み込むことが重要です。 QDataStreamがクラスで操作できるようにするには、これは の注文で必要です。
// Main read data function. There are only 4 bytes required, but maxSize == 0x4000 here:
qint64 BerUdp::readData(char *data, qint64 maxSize)
{
int n = m_buffer.read(data, maxSize);
// clear the data which has already read:
QByteArray& ba = m_buffer.buffer();
ba.remove(0, n); // m_buffer.size() == 0 after this
m_buffer.seek(0);
return n;
}
問題は、最初の読み取りの後、私は空のバッファを持っているということですので、私:問題が...あった場合QDataStream は、すべての要求された情報が読み取られたと仮定し、したがって、 リトライが読んでいませんbytesAvailable()メソッドは0を返します。
qint64 BerUdp::bytesAvailable() const
{
qint64 my_size = m_buffer.size();
qint64 builtin_size = QIODevice::bytesAvailable();
return (my_size + builtin_size); // == 0 after 1st read
}
だから私は、たとえば、クラスを使用するときにバイトが利用可能であり、どのように多く見つけることができません。
BerUdp udp;
QDataStream stream;
stream.setDevice(&udp);
...
QIODevice* dev = stream.device(); // 19 bytes available here
if (dev->bytesAvailable() > 0) // == true
{
quint32 val;
stream >> val;
}
if (dev->bytesAvailable() > 0) // == false
{
//...
}
QUdpSocket
のラッパーはどのように正しく書かれますか?
中間バッファを使用するという考えは、ロジックを別のQIODevice
由来のクラスに移すことにするまで、うまくいきました。