Все доброе утро! Столкнулся со следующей проблемой. Есть приложение, работающее на tcp сокетах. Все по классике: Подключение, прием/передача команд. После каждой выданной команды делаю flush. На 95% машин работает без проблем, однако есть машины, на которых каждый запуск приложения ведет себя по разному, поясню. Примерно каждый 3-4 запуск на запрос connect может не прийти никакого ответа -> как следствие, приложение не может подключиться, либо, прилетает конект, но следующая команда почему то дублируется, т.е. я выдаю одну строчку hello а в сеть улетает hellohello (смотрел через wireshark). Из-за таких проблем клиентам приходится запускать приложение на несколько раз... С чем это может быть связано? Работа с сокетом происходит следующим образом:
class TcpSocket : public QTcpSocket
{
Q_OBJECT
public:
explicit TcpSocket(QObject *parent = 0);
void sendData(QString, QMap<QString, QVariant> &, QString = "rpc", QString id = "", bool = true);
...
public slots:
void slotRecvData();
private:
void parseHeader(QString &);
private:
QString data;
int totalSize;
Logger *log;
};
TcpSocket :: TcpSocket(QObject *parent) :
QTcpSocket(parent),
log(LogManager::get_logging()->get_logger("Network")) {
connect(this, SIGNAL(readyRead()), SLOT(slotRecvData()));
init_error_map();
}
void TcpSocket :: slotRecvData() {
QString buf;
QMap<QString, QVariant> map;
QJsonDocument doc;
log -> set_param("SESSION", "Server");
while(this -> bytesAvailable())
try {
buf = this -> readAll();
if(!data.isEmpty()) {
data += buf;
}
else {
parseHeader(buf);
}
while(true) {
if(data.size() < totalSize) {
break;
}
else if(data.size() > totalSize) {
doc = QJsonDocument::fromJson(data.left(totalSize).toLocal8Bit().data());
log -> debug() << totalSize << "|" << doc.toJson().data() << '\n';
map = doc.toVariant().toMap();
emit dataReceived(map);
data = data.mid(totalSize);
parseHeader(data);
}
else {
doc = QJsonDocument::fromJson(data.toLocal8Bit().data());
log -> debug() << totalSize << "|" << doc.toJson().data() << '\n';
map = doc.toVariant().toMap();
emit dataReceived(map);
data.clear();
totalSize = 0;
break;
}
}
}
catch (NetworkHeaderException &s) {
log -> error() << "Error while recv cmd: " << s.what() << '\n';
log -> error() << "Ошибка данных сети: " << buf.toStdString() << "\n";
data.clear();
totalSize = 0;
setSocketError(QAbstractSocket::ProxyConnectionRefusedError);
disconnectFromHost();
break;
}
}
void TcpSocket :: sendData(QString cmd,
QMap<QString, QVariant> ¶ms,
QString type,
QString id,
bool log_cmd) {
QMap<QString, QVariant> map;
map["name"] = cmd;
map["params"] = params;
map["id"] = id;
map["type"] = type;
log -> set_param("SESSION", "Client");
try {
QVariant jsonVariant(map);
QString jsonStr = QJsonDocument::fromVariant(jsonVariant).toJson();
QByteArray _data = jsonStr.toUtf8().data();
_data.prepend("|");
_data.prepend(QString::number(_data.size() - 1).toStdString().data());
if(log_cmd) {
log -> debug() << _data.data();
}
write(_data);
flush();
}
catch (exception &e) {
log -> error() << "Error while send cmd: " << e.what() << '\n';
}
}
void TcpSocket :: parseHeader(QString &buf) {
int index = buf.indexOf('|');
if(index == -1) {
throw NetworkHeaderException();
}
bool res;
totalSize = buf.left(index).toInt(&res);
if(!res) {
throw NetworkHeaderException();
}
data = buf.mid(index + 1);
}