Эксперт С++
3950 / 1805 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
1

BytesToRaw (Indy 10)

21.06.2010, 19:48. Показов 6875. Ответов 1
Метки нет (Все метки)

Добрый день, уважаемые коллеги.

Реализовывая передачу изображения по протоколу UDP столкнулся с проблемой перевода TBytes в TMemoryStream.

Для теста создал новый проект. На форму поместил два TImage, один TButton, TIdUDPClient и TIdUDPServer.
В Image1 поместил PNG изображение (153 байта)

Настраиваю компоненты:
C++
1
2
3
4
UDPServer->DefaultPort = 2050;
UDPClient->Port = 2050;
UDPClient->Host = "127.0.0.1";
UDPServer->Active = true;
В событии OnClick для Button1 выполняю передачу объекта серверу:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
TMemoryStream *msS = new TMemoryStream();
 
TPngImage *png = new TPngImage();
png->Assign(Image1->Picture);
 
png->SaveToStream(msS);
msS->Position = soFromBeginning;
 
TByteDynArray DynArray = RawToBytes(msS,msS->Size);
 
delete png, msS;
png = NULL, msS = NULL;
 
UDPClient->SendBuffer(DynArray);
Передача проходит на "ура". Теперь обрабатываю событие OnUDPRead:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void __fastcall TForm1::UDPServerUDPRead(TIdUDPListenerThread *AThread, TBytes AData,
                    TIdSocketHandle *ABinding)
{
  TMemoryStream *msR = new TMemoryStream();
  TPngImage *png = new TPngImage();
 
  BytesToRaw(AData,msR,AData.Length);  // проблемое место
  msR->Position = soFromBeginning;
  png->LoadFromStream(msR);
  Image2->Picture->Graphic = png;
 
  delete png, msR;
  png = NULL, msR = NULL;
}
Картинка появляется в Image2, но при закрытии формы возникает Access Violation.

Функция BytesToRaw в третьем параметре требует int Size. Я передаю ей размер полученных данных (AData.Length) получаю всё тот же AV.
Пробую передать размер TBytes (пробовал также для TByteDynArray):
C++
1
BytesToRaw(AData,msR,sizeof(AData));
В этом случае поток msR имеет нулевую длину и ссылается в NULL

Пробовал работать с этой функцией без сетевой передачи (далее изменённый код OnClick для Button1):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  TMemoryStream *msS = new TMemoryStream();
 
  TPngImage *png = new TPngImage();
  png->Assign(Image1->Picture);
 
  png->SaveToStream(msS);
  msS->Position = soFromBeginning;
 
  TByteDynArray DynArray = RawToBytes(msS,msS->Size);
 
  BytesToRaw(DynArray,msS,sizeof(DynArray));
  msS->Position = soFromBeginning;
  png->LoadFromStream(msS);
  mage2->Picture->Graphic = png;
 
  delete png, msS;
  png = NULL, msS = NULL;
Тогда ошибок не возникает.

Подскажите пожалуйста, что я делаю неправильно?
2
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.06.2010, 19:48
Ответы с готовыми решениями:

Indy 8 и Indy 10. Старая и новая версия
Есть строчки var c: char; myFile: file; HasChild: bool; s,RecvBuf,path: string; ...

Indy
начал читать книгу "Книга Indy in Depth. Глубины Indy" там пример with IndyClient do begin...

indy 10
Поставил indy 10,так как был необходим модyль IdAttachmentFile,но как оказалось после yстановки в...

Книга по Indy
Какие есть книги по Indy, в которых учат свободно делать собственные чаты и авторизироваться на...

1
Эксперт С++
3950 / 1805 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
23.06.2010, 13:57  [ТС] 2
Проблема с приёмом/передачей решена.

Для преобразования TBytes в TStream необходимо использовать функцию WriteTIdBytesToStream (обратная ей функция - ReadTIdBytesFromStream).

Если кому-то пригодится (а точно пригодится), в верхнем исходнике необходимо заменить две строчки.

В событии OnClick меняем девятую строчку на:
C++
1
2
TByteDynArray DynArray;
ReadTIdBytesFromStream(msS,DynArray,msS->Size);
А в событии OnUDPRead меняем седьмую строчку на:
C++
1
WriteTIdBytesToStream(msR,AData,AData.Length,0);
Теперь необходимо только реализовать разбивку потока на максимально возможные пакеты (UDPClient->BufferSize)
3
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.06.2010, 13:57
Помогаю со студенческими работами здесь

Indy и HTTPS
Добрый день. Необходимо отправлять POST запрос на https ресурс. Решил реализовывать через indy. Но...

Indy client
Здравствуйте, пишу на c++. кто-нибудь может разобраться с Indy Clients в BorlandC++6 перерыл...

Get Запрос в Indy
День добрый. Вопрос такой при Get запросе данные сразу заносятся в память или частями? пример ...

Indy модули
проблема в трех картинках Как решить?

Компоненты indy
Всем привет. А вот с помощью компонентов indy можно работать в интернете ? или они для сети...

Indy и UserGate
Здравствуйте! Есть клиентская программа, которая стоит на компьютерах и отправляют запросы на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru