crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> "Склеивание" сообщений ТСР
pwp2008
  опции профиля:
сообщение 19.10.2015, 19:31
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 29
Регистрация: 19.12.2014
Пользователь №: 4299

Спасибо сказали: 0 раз(а)




Репутация:   0  


Подскажите пож-та, встречалось ли Вам отправленные друг за другом сообщения (клиентом) получать в сервере "склееном" виде, как если бы это было одно сообщение. В чем причина такой работы по протоколу TCP\IP ? Разрулить эту проблему удалось несколько искусственным способом, хотя здесь может подойти и передача длины сообщения и/или контрольный суммы. Видимо так склеены могут быть не 2, а даже больше последовательных сообщений.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
ViGOur
  опции профиля:
сообщение 20.10.2015, 21:03
Сообщение #2


Мастер
******

Группа: Модератор
Сообщений: 3291
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Ты не понял.
TCP стеку все равно, что в него попадает видео, звук или сообщения, он как получил так и отдал, твоя забота уже правильно разобрать переданые тобой данные.
За пример можно взять лог файл, если не сделать правильное форматирование, то логи будут не читабельны, то же самое и здесь.

Есть 3 варианта того, какими ты можешь получить свои сообщения:
1. Не полное сообщение (в том случае, если ты забираешь данные быстрей, чем они приходит)
2. Полное сообщения (идеальное стечение обстоятельств)
3. Склеенное сообщение (в том случае, если ты забираешь медленней, чем они приходят и склееным может быть как часть следующего пакета, так и несколько пакетов...)

Обычно, чтобы всегда были идеальные условия используют структуру приведенную мной выше, по следующей схеме:
1. При поступленни данных читаем первые 4 байта, и приводим их к int, чтобы получить размер буфера.
2. Читаются столько байт, сколько указанно в первых четырех байтах полученных в 1 пункте.
3. Что-то там делаем с полученными данными.
4. Переходим к 1 пункту.

Или чтобы не писать свой протокол над TCP, отправлять сообщения одной длины, например 1024 байта...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
pwp2008
  опции профиля:
сообщение 25.10.2015, 18:11
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 29
Регистрация: 19.12.2014
Пользователь №: 4299

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 20.10.2015, 21:03) *

Наработка по "склеиванию" сообщений такова :
Имеем 2 простых приложения : 1-Сервер 2-Клиент (хотя кто из них Сервер, кто Клиент
-чисто условное деление). Сервер по кнопке на своем окне высылает клиенту сообщение
по сети ТСР\IP. Соединение между ними было преварительно установлено : сервер
ждал соединения, Клиент - соединился и ждет сообщений от сервера. После получения
его выдает его в свое окно. Так вот, если сообщение сервера оформлено как одно:
string parcel_x = "wwwwwwwwwwwwwwwwwwwwwwwwwwwww";
int numBytes = firstClientSocket->write(parcel_x.data(),parcel_x.length());
то Клиент его получает и показывает. Если же поставить 2 сообщения подряд :

string parcel_x = "wwwwwwwwwwwwwwwwwwwwwwwwwwwww";
int numBytes = firstClientSocket->write(parcel_x.data(),parcel_x.length());
string parcel_z = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
int numBytes = firstClientSocket->write(parcel_z.data(),parcel_z.length());
......................................
то Клиент получает только одно, но "склеенное" из 2-х сообщение. Хотелось бы
понять причины этого и по возможности "разделить" сообщения, чтобы они приходили
на клиент в виде 2 сообщений.
Проверено следующее :
Если второе сообщение выполнить по слоту однократного таймера через ххх мсек,
то тогда склейки на клиенте нет :
string parcel_x = "wwwwwwwwwwwwwwwwwwwwwwwwwwwww";
int numBytes = firstClientSocket->write(parcel_x.data(),parcel_x.length());
int xxx = 50; // интервал для срабатывания
QTimer::singleShot(xxx,this,SLOT(slotMessage_2()));
..............................

void PRG::slotMessage_2()
{
string parcel_z = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
int numBytes = firstClientSocket->write(parcel_z.data(),parcel_z.length());
}
и каждое сообщений приходит отдельно. Причем , уже при xxx > 11 .
Если xxx=1, то сообщения "склеиваются" и в таком исполнении.
Явное указание в сервере типа соединения = Qt::DirectConnection в методе connect :
bool QObject::connect ( const QObject * sender, const char * signal,
const QObject * receiver, const char * method,
Qt::ConnectionType type = Qt::AutoConnection ) [static]

"склеивания" не убирает( похоже может на Клиенте нужно было так же сделать ? на Клиенте я не ставил, упустил)
Тексты приложений не привожу - это просто пример из Qt по технологии Клиент-Сервер.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Влад
  опции профиля:
сообщение 26.10.2015, 14:45
Сообщение #4


Участник
**

Группа: Участник
Сообщений: 146
Регистрация: 20.3.2009
Из: Санкт-Петербург
Пользователь №: 627

Спасибо сказали: 46 раз(а)




Репутация:   8  


Цитата(pwp2008 @ 25.10.2015, 18:11) *
......Клиент получает только одно, но "склеенное" из 2-х сообщение. Хотелось бы
понять причины этого и по возможности "разделить" сообщения, чтобы они приходили на клиент в виде 2 сообщений.
......
и каждое сообщений приходит отдельно. Причем , уже при xxx > 11 .
Если xxx=1, то сообщения "склеиваются" и в таком исполнении.

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

Правильный подход тебе описал коллега ViGOur.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 25.1.2020, 8:29