Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QTcpSocket::write() - как гарантировать пересылку данных одним пакетом?
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие
fluffyMan2000
Добрый день.

Я новичек в сетевом программировании, но все же.

Пишу клиент-серверную систему. Есть qt клиент и qt сервер. Клиент отправляет запрос (json), сервер обрабатывает запрос и генерирует json ответ.

На стороне сервера отправка данных реализована через метод socket-> write(data), где data - это строка.

На стороне клиента при получении данных вызывается метод slotReadyRead(), подключенный к сигналу readyRead().

Данные считываются методом socket->readAll().

Но вот проблема, когда сервер передаёт небольшую строку, то клиент принимает ее полностью. Если большую строку (большой Джейсон), то строка передаётся частями. То есть один вызов сигнала readyRead не означает получение ПОЛНОГО сообщения от сервера, насколько я понимаю. Отсюда вопрос, как за один раз передать ВСЮ БОЛЬШУЮ строку?
fluffyMan2000
Цитата(fluffyMan2000 @ 31.10.2013, 19:25) *
Добрый день.

Я новичек в сетевом программировании, но все же.

Пишу клиент-серверную систему. Есть qt клиент и qt сервер. Клиент отправляет запрос (json), сервер обрабатывает запрос и генерирует json ответ.

На стороне сервера отправка данных реализована через метод socket-> write(data), где data - это строка.

На стороне клиента при получении данных вызывается метод slotReadyRead(), подключенный к сигналу readyRead().

Данные считываются методом socket->readAll().

Но вот проблема, когда сервер передаёт небольшую строку, то клиент принимает ее полностью. Если большую строку (большой Джейсон), то строка передаётся частями. То есть один вызов сигнала readyRead не означает получение ПОЛНОГО сообщения от сервера, насколько я понимаю. Отсюда вопрос, как за один раз передать ВСЮ БОЛЬШУЮ строку?


решение, если кому интересно:

все же подумал и решил проблему следующим образом: на стороне сервера при отправке сообщения к сообщению добавляю признак конца строки. на стороне клиента при приеме сообщения делаю:

 QString response;

    while(1)
    {
        response += QString(m_pTcpSocket->readAll());

        if (response.contains("\n"))
        {
            break;
        } else
        {
            m_pTcpSocket->waitForReadyRead(100);
        }
    }



насколько это правильно — не знаю. но работает.
mezmay
Обычно в начало пакета вставляют размер,
а прием целого пакета по событию примерно так:
void CMyClass::onReceive()
{
    QDataStream in(m_pTcpSocket);

    for(;;)
    {
        if(m_nextBlockSize == 0)
        {
            if(m_pTcpSocket->bytesAvailable() < sizeof(m_nextBlockSize))
            {
                break;
            }
            else
            {
                in >> m_nextBlockSize;
            }
        }

        if(m_pTcpSocket->bytesAvailable() < m_nextBlockSize)
        {
            break;
        }

        // Вызов функции обработки принятых данных
        receiveCmd(m_pTcpSocket);

        m_nextBlockSize = 0;
    }
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2018 IPS, Inc.