crossplatform.ru

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

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


Студент
*

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

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




Репутация:   0  


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


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

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

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




Репутация:   40  


4 байта было сказано для примера, ты сам решай, какой длины будет у тебя поле длина пакета. К тому же жестко указывать размер нельзя, а только sizeof(int), так как под разными системами int разного размера.
4 байта могут так же прийти по частям, это маловероятно, но может быть, например при медленном соединении или при крайней загруженности системы или сети.
Блоки не переставляются и контрольные суммы по идее не нужны, так как TCP протокол гарантирует доставку пакета
Набросал на коленке пример реализации:
struct sDataPacket
{
    int nLen;
    char *pData;
};

sDataPacket *getPacket( int socket )
{
    sDataPacket *pPacket = new sDataPacket;
    // Читаем первые 4 байта
    int nLen = sizeof(pPacket->nLen);
    char *pBuff = new char[nLen];
    do
    {
        int nRet = recv( socket, pBuff, nLen, 0 );
        if( nRet == sizeof(pPacket->nLen) )
        {
            // Переводим прочитанные 4 байта в длину
            memcpy((void*)&pPacket->nLen, (void*)pBuff, nLen);
            // Читаем указанное количество байт данных
            if( pPacket->nLen > 0 )
            {
                pPacket->pData = new char[pPacket->nLen];
                nRet = recv( socket, pPacket->pData, pPacket->nLen, 0 );
                if( nRet < pPacket->nLen )
                {
                    // Дочитываем
                }
            }
            break;
        }
        else
        {
            // Дочитываем
        }
    }while(true);
    delete []pBuff;

    return pPacket;
}
Тебе только осталось дописать докачку...

Как вариант, во избежании склеивания, можно сделать клиент серверный диалог с подтверждением, например:
1. Клиент отправляет пакет
2. Сервер получает пакет
3. Сервер отправляет подтверждение о получении пакета
4. Клиент получает подтверждени и идет к 1 пункту
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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


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




RSS Текстовая версия Сейчас: 22.11.2024, 9:59