QTcpSocket получающий перевод

У меня проблемы с получением перевода.

QTcpSocket-> readAll () не читает достаточно байтов при отправке на него. Когда я отправляю 15 байтов, он читает только некоторую его часть и ничего не делает. Что я делаю не так?

QByteArray array;

array = socket->readAll(); //just reads some part, not fully.

Зачем?

Извините за мой английский.

С уважением.

1

Решение

Скорее всего, сокет еще не получил все данные, когда вы звоните readAll(), Это из-за связи TCP происходит в маленькие пакеты (у каждого есть приблизительно 1 КБ данных, в зависимости от многих вещей). Эти пакеты составляют поток, в который другой конец линии связи записывает байты. Вы должны собрать их на приемной стороне. Как вы их собираете, должно быть определено в протоколе.

Чтобы решить эту проблему, вы должны подождать все ожидаемые данные, прежде чем собирать их. Иногда неизвестно, сколько данных ожидается, если вы не прочитаете их (в зависимости от протокола).

Допустим, вы хотите реализовать протокол, который говорит: «все, пока разрыв строки не является чем-то, что мы называем сообщение«. Теперь вы хотите получить такой сообщение. Это делается путем последовательного чтения и добавления в целевой буфер (например, ваш QByteArray) пока не наступит разрыв строки. Однако есть еще одна вещь: когда вы ожидаете второго сообщение, это может быть сразу после первого в потоке TCP, так что вы просто читаете не только конец первого сообщения, но и начало второго. Просто имейте это в виду.

Если вы не имеете дело с подключением сигнального слота, вы можете написать синхронный приемник для таких разделенных новой строкой сообщений, как это:

QByteArray array;

while(!array.contains('\n')) {
socket->waitForReadyRead();
array += socket->readAll();
}

int bytes = array.indexOf('\n') + 1;     // Find the end of message
QByteArray message = array.left(bytes);  // Cut the message
array = array.mid(bytes);                // Keep the data read too early

processMessage(message);

При обращении QTcpSocket::readyRead()Можете сделать что-то подобное.

void MyClass::socketReadyRead() // connected to QTcpSocket::readyRead() signal
{
array += socket->readAll();

if(array.contains('\n')) {
int bytes = array.indexOf('\n') + 1;     // Find the end of message
QByteArray message = array.left(bytes);  // Cut the message
array = array.mid(bytes);                // Keep the data read too early

processMessage(message);

socketReadyRead();                       // re-call myself to process more
}
}

Когда вы хотите прочитать все, отправленное через одно TCP-соединение (пока оно не будет закрыто одноранговым узлом), вы можете дождаться этого события либо блокирующим способом, либо обработать данные в слоте, подключенном к соответствующему сигналу: QTcpSocket::disconnected,

Блокировка:

socket->waitForDisconnected();
QByteArray array = socket->readAll();

Неблокирующая (обработка сигналов с использованием слотов):

void MyClass::socketReadyRead() // connected to QTcpSocket::readyRead() signal
{
array += socket->readAll();
// Do NOT process yet!
}

void MyClass::socketDisconnected() // connected to QTcpSocket::disconnected() signal
{
processMessage(array);
}

Альтернативное неблокирующее решение (по сути то же самое):

// You don't have to connect to QTcpSocket::readyRead() signal in this case

void MyClass::socketDisconnected()
{
processMessage(socket->readAll());
}
6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]