Я пишу AsyncSocket, который использует QTcpSocket для работы с некоторыми серверами. Они (серверы) были написаны давно, и у меня нет возможности их изменить.
Итак, проблема в - отсутствие сигнала readyRead, если сервер не смог распознать сообщение (потому что он ничего не сделал с типом сообщения default). Я думаю, что это проблема сервера, потому что он все равно должен ответить ... но это не мой собственный код, и я должен использовать его как есть.
Я думал использовать QAbstractSocket::waitForReadyRead(int msecs), но нашел в Документация Qt (конец раздела «подробности»):
Note: We discourage the use of the blocking functions together with signals. One of the two possibilities should be used.
Итак, я немного запутался, почему мне не следует использовать такой метод блокировки:
void AsyncSocket::send(const QByteArray &msg)
{
socket->write(msg);
if (!socket->waitForReadyRead(msecs))
qDebug() << "Warning! ReadyRead were not emitted";
}
Сервер работает так:
switch(received_msg.type)
{
case TYPE_ONE: // do smth
break;
case TYPE_TWO: // do smth
break;
case TYPE_N: // do smth
break;
default:
// do NOTHING
}
Мои занятия:
class AsyncSocket
{
public:
void connectToHost(const QString &host, qint16 port);
void send(const QByteArray &msg);
void disconnectFromHost();
// other public members
public slots:
void connected();
void readyRead();
};
ОБНОВИТЬ: может быть полезно перехватывать отсутствующие сигналы readyRead для организации очереди сообщений с помощью AsyncSocket
Да, ты прав. Qt doc говорит, что использовать блочные методы - не лучшая идея. Но не совсем ясно, какова альтернатива.
Тогда у вас есть 2 варианта. Либо вы ждете, как описано выше (но это заблокирует ваше приложение и обычно не рекомендуется), либо вы используете QTimer для запуска тайм-аута, если пройдет много времени до того, как будет выпущен readyRead





Я решил проблему, следуя совету Феликс по поводу QTimer, вот так:
class AsyncSocket
{
public:
void connectToHost(const QString &host, qint16 port);
void send(const QByteArray &msg);
void disconnectFromHost();
// other public members
signals:
void dataReady(const QByteArray &data);
public slots:
void connected();
void readyRead();
private slots:
// I created the timer timeout signal here connected in AsyncSocket constructor
void missRead();
private:
QTimer *timer; // and timer pointer here allocated in constructor also
};
Я запускаю таймер, когда пользователь отправляет сообщение:
bool AsyncSocket::send(const QByteArray &msg, int responseSize)
{
// successfull sending code here
timer->start(msecs);
return true;
}
И я использую сигналы для обработки таких случаев чтения:
void AsyncSocket::readyRead() // successfull reading
{
if (socket->bytesAvailable() == responseSize) // buffer has all data
{
timer->stop();
emit (dataReady(socket->readAll()));
// reset device, clear buffer, etc.
}
}
void AsyncSocket::missRead() // server stoped to reply
{
timer->stop();
emit(dataReady(QByteArray()));
// reset device, clear buffer, etc.
}
Я не понимаю, о чем вы спрашиваете. Итак, ваша проблема в том, что сервер не отвечает на определенные сообщения, и вы хотите определить, когда это произойдет?