Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Некорректная работа с памятью

22K
02 ноября 2011 года
*Baikal*
13 / / 20.03.2007
Здравствуйте.
Возникла трабла непонятного происхождения при работе с памятью.
Есть следующий код:

 
Код:
while (...){
        char* buff = dataBuffer->ptr + dataBuffer->size;

        if ((rcv_size = recv(recvSocket, buff, pack_lng, 0)) > 0){
            dataBuffer->size += rcv_size;
        }
}


dataBuffer - структура, которая описывает буфер определенного размера, куда сваливаются все данные, полученные с сокета,
buff- указатель на хвост буфера
В цикле получаем данные с сокета и дописываем их в конец буфера.
Данные нормально приняты и записаны в буфер.
После получения данные из буфера пишутся в файл.

Возникла необходимость выкидывать первые четыре байта из каждой порции данных,
полученной с сокета. Первое и пока единственное, что пришло на ум:
Код:
char tmp_buff[1500];

while (...){
    char* buff = dataBuffer->ptr + dataBuffer->size;

    if ((rcv_size = recv(recvSocket, tmp_buff, pack_lng, 0)) > 0){
        memmove(buff,&tmp_buff[4],rcv_size-4);
        dataBuffer->size += rcv_size-4;
    }
       
}


Создаем временный буфер tmp_buff и записываем данные в него,
затем перемещаем(или копируем) данные из него в основной буфер со смещением
в четыре байта.
В этом случае у нас происходят странности: при нескольких сеансах передачи
итоговые фаилы имеют различный размер, причем их размер варьируется кратно четырем:
отличаются по размерам на 4, 8, 16 ... байт. При том что они должны быть одинаковы
:confused::confused::confused:

Буду очень признателен за помощь
412
02 ноября 2011 года
grgdvo
323 / / 04.07.2007
Я не очень понял... Вам нужно избавиться от четырех первых байт что ли?
Ну, затрите их сверху сдвигом на 4 байта вашего buff.
И вы неправильно используете memmove, похоже перепутали указатели куда-откуда копируем.
Сейчас вы копируете в buff из tmp_buff (с 4 элемента)

 
Код:
NAME
       memmove - copy memory area

SYNOPSIS
       #include <string.h>
       void *memmove(void *dest, const void *src, size_t n);
22K
02 ноября 2011 года
*Baikal*
13 / / 20.03.2007
Цитата: grgdvo
Я не очень понял... Вам нужно избавиться от четырех первых байт что ли?
Ну, затрите их сверху сдвигом на 4 байта вашего buff.
И вы неправильно используете memmove, похоже перепутали указатели куда-откуда копируем.
Сейчас вы копируете в buff из tmp_buff (с 4 элемента)



Мне как раз и нужно копировать из tmp_buff в buff
Я получаю порцию данных с сокета в tmp_buff, убираю заголовок в 4 байта
и дописываю "отчищенные" данные в конец буфера buff, где они хранятся непрерывным куском

278
02 ноября 2011 года
Alexander92
1.1K / / 04.08.2008
А почему нельзя принять данные в два вызова recv() - первый раз те самые 4 байта, а второй раз полезную информацию? :)
22K
03 ноября 2011 года
*Baikal*
13 / / 20.03.2007
Неплохой вариант, но клиентскую прогу пишет другая контора, при этом такой вариант развития событий не предусмотрен утвержденным протоколом. Как еще можно выделить участок с полезной нагрузкой из блока поступивших данных?
Наверняка, вариант, реализованный мной - не единственный. Может быть кто-нибудь подскажет другие способы?
412
03 ноября 2011 года
grgdvo
323 / / 04.07.2007
Цитата: *Baikal*
Мне как раз и нужно копировать из tmp_buff в buff
Я получаю порцию данных с сокета в tmp_buff, убираю заголовок в 4 байта
и дописываю "отчищенные" данные в конец буфера buff, где они хранятся непрерывным куском



Да точно... невнимательно посмотрел на recv.

Ну все равно непонятна логика. Вы чего ождиаете?
У вас каждый раз recv честно отнимается по 4 байта,
таких recv за сеанс получается 2, 3, 4... вот и разница набигает 4, 8, 12 байт.
По-моему что написали, то и получили :) Может все-таки, ошибка в логике?
pack_lng - это что за величина?

22K
03 ноября 2011 года
*Baikal*
13 / / 20.03.2007
На передающей стороне происходит следующее:
с диска считывается файл по куску в 1400 байт. К этому куску добавляется
заголовок в 4 байта и вот эти вот 1404 байта я получаю у себя. Потом я отбрасываю
четырехбайтовый заголовок, а блок, записываю в буфер. И продолжаю писать
в буфер до тех пор, пока передающая сторона полностью не отправит мне файл.
После этого соединение разрывается. А из буфера данные перекидываются в файл.

В итоге исходный файл и файл, записанный мной, отличаются по размерам, не более чем
на килобайт при размере самого файла в несколько метров. И разница в размерах кратна
четырем.

При этом, если передающая сторона не добавляет заголовок, и я убираю код,
по обработке заголовков, то никаких проблем не возникает...

Что может быть - понять не могу, может дело в опциях компилятора, может еще в чем-то
Еще какие-нибудь мысли есть? даже не представляю, какую сторону копать :(
278
03 ноября 2011 года
Alexander92
1.1K / / 04.08.2008
Еще такой вопрос возник: зачем вы сразу принимаете данные в "конечный" буфер? Не легче ли было бы принять в какой-то сторонний буфер, а потом просто скопировать из него с нужного места в dataBuffer?
260
03 ноября 2011 года
Ramon
1.1K / / 16.08.2003
Цитата: Alexander92
Еще такой вопрос возник: зачем вы сразу принимаете данные в "конечный" буфер? Не легче ли было бы принять в какой-то сторонний буфер, а потом просто скопировать из него с нужного места в dataBuffer?



Копирование тряпок оптимизируют :D.

22K
04 ноября 2011 года
*Baikal*
13 / / 20.03.2007
Цитата: Alexander92
Еще такой вопрос возник: зачем вы сразу принимаете данные в "конечный" буфер? Не легче ли было бы принять в какой-то сторонний буфер, а потом просто скопировать из него с нужного места в dataBuffer?



Смотрите код в первом посте...
Ramon, не могли бы вы предложить альтернативный вариант выполнения этой операции?

260
04 ноября 2011 года
Ramon
1.1K / / 16.08.2003
Цитата: *Baikal*
Смотрите код в первом посте...
Ramon, не могли бы вы предложить альтернативный вариант выполнения этой операции?



Расскажите по подробнее, что представляет из себя протокол, какие данные по нему гоняются и самое главное, что есть эти загадочные 4 байта.

412
04 ноября 2011 года
grgdvo
323 / / 04.07.2007
Может этих 4 байт и нет вообще? :) Вы не пробовали смотреть на содержимое любого приходящего recv.
20K
05 ноября 2011 года
sem2711
124 / / 23.09.2009
Предлагаю попробовать следующее: в функции recv указывать конкретно на первый элемент temp_buff, т.е.

 
Код:
rcv_size = recv(recvSocket, &tmp_buff[0], pack_lng, 0);
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог