Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Socket принимает данные не полностью. / 14 сообщений из 14, страница 1 из 1
03.12.2013, 08:41
    #38486891
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
Здравствуйте. Переписываю один проект под Qt. Читаю данные из сокета(QTcpSocket) по сигналу readyRead. Но не могу понять одно, почему данные приходят не полностью. Вернее сами данные приходят, то полностью но как-то частями что ли... К примеру сервер посылает такие данные(очередность пакетов):

  1.Привет
  2.Как
      пауза в отправке данных
  3.Дела

Пока не будет отправлен пакет #3 я не увижу данных пакета 1 и 2. Пробовал устанавливать буфер setReadBufferSize но это ничего не дает. Как я понимаю тут как только приходят данные, то срабатывает сигнал readyRead? Но почему тогда происходит такая ситуация?

Код: sql
1.
2.
3.
4.
5.
void MainWindow::on_data()
{
    QByteArray data=tcpSocket->readAll();
    .... Какая-то обработка данных....
}



Ранее я работал с сокетами в Java и C# и делал так и без проблем получал все порции данных сразу, даже если приходила часть отправленного пакета:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
int receivedBytes;
byte[] dataBuffer = new byte[Session.BUFFER_SIZE];

InputStream stream=mTcpClient.getInputStream();

while ((receivedBytes = stream.read(dataBuffer, 0, dataBuffer.length)) != -1) {
	обработка_данных(dataBuffer, receivedBytes);
}



Как сделать подобное в QT5? Спасибо.
...
Рейтинг: 0 / 0
03.12.2013, 11:21
    #38487060
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
GorloPavel,
Пока не будет отправлен пакет #3 я не увижу данных пакета 1 и 2

Это буферизация, надо на посылающей стороне делать flush по окончании пакета.
...
Рейтинг: 0 / 0
03.12.2013, 15:21
    #38487523
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
GorloPavel...сервер посылает такие данные(очередность пакетов)....

судя по вопросу - не понимание протокола который юзаете.
НЕТ пакетов на TCP уровне ну НЕТУ!!! хоть плач...

изучайте данный уровень
(круглый)
...
Рейтинг: 0 / 0
03.12.2013, 15:35
    #38487559
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
kolobok0GorloPavel...сервер посылает такие данные(очередность пакетов)....

судя по вопросу - не понимание протокола который юзаете.
НЕТ пакетов на TCP уровне ну НЕТУ!!! хоть плач...

изучайте данный уровень
(круглый)

Он вероятно имел в виду пакеты уже верхнего уровня, уровня протокола приложения.
Типа как в HTTP GET/PUT.
...
Рейтинг: 0 / 0
03.12.2013, 15:41
    #38487574
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
MasterZivkolobok0пропущено...


судя по вопросу - не понимание протокола который юзаете.
НЕТ пакетов на TCP уровне ну НЕТУ!!! хоть плач...

изучайте данный уровень
(круглый)

Он вероятно имел в виду пакеты уже верхнего уровня, уровня протокола приложения.
Типа как в HTTP GET/PUT.
Так и есть. У меня свой протокол в приложении. Помогло вот это:
Код: plaintext
1.
2.
3.
4.
5.
while(tcpSocket->bytesAvailable())
{
    QByteArray data=tcpSocket->readAll();
    packetSplitter->setByteArray(&data,data.length());
}



Все равно всем спасибо!
...
Рейтинг: 0 / 0
03.12.2013, 17:08
    #38487772
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
GorloPavel,


Я не понял, а где flush ?
...
Рейтинг: 0 / 0
03.12.2013, 18:13
    #38487888
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
MasterZiv...а где flush ?

сеанс телепатии закончился не удачно? )

не удержался, сорри...
(круглый)
...
Рейтинг: 0 / 0
03.12.2013, 18:26
    #38487900
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
GorloPavel...Помогло вот это..

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

Код: plaintext
1.
обработка_данных(dataBuffer, receivedBytes);



сказать сложно, но сдаётся мне что Вы там не ожидаете половинку поля на приёме :))

удачи вам, она Вам потребуется
в гаданиях по луне
(круглый)
ЗЫ
Даже флэш - не поможет во всех случаях!!!
ЗЫ ЗЫ
Всё дело в волшебных пузырьках, и как разливать в них живительную влагу способе юзанья. Если Вы воспринимаете, что на уровне сокетов(а именно так Вы задали вопрос, а не о каких то там слоях распологающихся выше!) Вы ожидаете поток - работать будет (флэш тут будет выступать в роли оптимизации по скорости передачи). А вот если думаете, что прийдёт размер от некоего буфера(если ещё Вы ожидаете его асинхронно, и не фиксированную длину хедэра пакета!!!) - то тут Вы глубоко ошибаетесь. Оно может отдать: и один байт, и сразу два пакета(если нет синхронизации на логическом уровне!!!). Вот о чём речь. Т.е. пинганули(или читай начали скачивать по фтп пару гигоффф) Ваш сервак не 10 юзверей, а 100 000 и привет семье - суши вёсла. Если Вы делаете не хэйлох-ты мир, то мучение тому пользователю, что будет юзать сей творческий Ваш посыл... вот такие дела...
...
Рейтинг: 0 / 0
04.12.2013, 04:38
    #38488276
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
kolobok0GorloPavel...Помогло вот это..

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

Код: plaintext
1.
обработка_данных(dataBuffer, receivedBytes);



сказать сложно, но сдаётся мне что Вы там не ожидаете половинку поля на приёме :))

удачи вам, она Вам потребуется
в гаданиях по луне
(круглый)
ЗЫ
Даже флэш - не поможет во всех случаях!!!
ЗЫ ЗЫ
Всё дело в волшебных пузырьках, и как разливать в них живительную влагу способе юзанья. Если Вы воспринимаете, что на уровне сокетов(а именно так Вы задали вопрос, а не о каких то там слоях распологающихся выше!) Вы ожидаете поток - работать будет (флэш тут будет выступать в роли оптимизации по скорости передачи). А вот если думаете, что прийдёт размер от некоего буфера(если ещё Вы ожидаете его асинхронно, и не фиксированную длину хедэра пакета!!!) - то тут Вы глубоко ошибаетесь. Оно может отдать: и один байт, и сразу два пакета(если нет синхронизации на логическом уровне!!!). Вот о чём речь. Т.е. пинганули(или читай начали скачивать по фтп пару гигоффф) Ваш сервак не 10 юзверей, а 100 000 и привет семье - суши вёсла. Если Вы делаете не хэйлох-ты мир, то мучение тому пользователю, что будет юзать сей творческий Ваш посыл... вот такие дела...
Все это делает обработка_данных(dataBuffer, receivedBytes); 4 байта заголовок пакета(размер), остальное "полезные" данные... Вообщем все предусмотрено... Вообщем все отлично :)
...
Рейтинг: 0 / 0
04.12.2013, 04:39
    #38488277
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
MasterZivGorloPavel,
Я не понял, а где flush ?
А где тут отправка данных, после которого должен быть flush? :)
...
Рейтинг: 0 / 0
04.12.2013, 07:39
    #38488302
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
GorloPavel,

На отправляющей стороне.
...
Рейтинг: 0 / 0
04.12.2013, 13:20
    #38488754
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
MasterZivGorloPavel,

На отправляющей стороне.

Хахаха.
...
Рейтинг: 0 / 0
13.12.2013, 11:47
    #38499746
sterewert
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
Сигнал onReadyRead испускается на каждую порцию данных которая вам пришла, эти данные надо вычитывать до конца и собрать вместе. Общий размер данных вычитывается из хедера http запроса.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
void QSocketThread::onReadyRead() {
...........

    con_length = HeaderByName("Content-Length").toInt();

    if (!socket->atEnd()) {
        con_length -= socket->bytesAvailable();

        xmlb += socket->readAll();
    }
.......
}
...
Рейтинг: 0 / 0
13.12.2013, 11:48
    #38499747
sterewert
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Socket принимает данные не полностью.
Если же у вас не http запрос, то сами думайте как передавать размер данных принимающей стороне.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Socket принимает данные не полностью. / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]