Модераторы: Snowy, Poseidon, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамический массив в Record и отправка его через 
:(
    Опции темы
lux16
  Дата 18.4.2011, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 10.8.2010

Репутация: нет
Всего: нет



Привет, народ. Столкнулся с проблемой. Есть такая структура:
Код

 aData = Packed Record
    aArr:   Array Of String;
  End;

И такие процедуры:
Код

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  rec:  aData;
begin
  SetLength( rec.aArr, 3 );
  rec.aArr[1] := '1';
  rec.aArr[2] := '2';
  Socket.SendBuf( rec, SizeOf( rec ) );
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  rec:  aData;
  len:  Byte;
begin
  len := Socket.ReceiveLength;
  Socket.ReceiveBuf( rec, len );
  Memo1.Lines.Add( rec.aArr[1] );
end;

И в Memo1 просто добовляется пустая строка, но если в процедуре procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket); добавить строку ShowMessage( '' );, то есть привести ее к такому виду:
Код

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  rec:  aData;
begin
  SetLength( rec.aArr, 3 );
  rec.aArr[1] := '1';
  rec.aArr[2] := '2';
  Socket.SendBuf( rec, SizeOf( rec ) );
  ShowMessage( '' );
end;

То все работает, и в Memo1 добовляется строка. Подскажите, что кто знает
PM MAIL   Вверх
Snowy
Дата 18.4.2011, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



А какой смысл передавать по сети массив указателей на строку?
Даже в пределах одной программы это странная затея...
А во втором случае работает потому, что ты стопоришь выход из функции.
Если остановки не будет, то твои строки перестают существовать.
А так, как ты переслал не строки, а указатели на них, то эти указатели будут показывать на ничто, т.к. строк в памяти уже нет.
PM MAIL   Вверх
lux16
Дата 18.4.2011, 14:25 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 10.8.2010

Репутация: нет
Всего: нет



Либо я что - то не понял, либо что - то не так. Мне нужно передавать строки переменной величины, то есть я их размер не знаю. Для этого мне надо Array Of String. Как его передать расскажите, никакой указатель я не передаю

Добавлено через 10 минут и 5 секунд
Всем спасибо, нашел решение. На форуме programmersforum помогли. После отправки пишу такой код Application.ProccesMessages;
PM MAIL   Вверх
Snowy
Дата 18.4.2011, 15:03 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Что такое string?
Это указатель на блок данных в памяти, где находится текст и длина строки.
Таким образом, array of string - массив указателей.
Вот его ты и передаёшь.
Повторяю - ты передаёшь не строки.
Как только ты выйдешь за пределы своей программы (например пересылка между двумя компьютерами или двумя программами), твои указатели потеряют весь смысл.

Это, что касается того, что ты делаешь неправильно.
Теперь о том, как нужно делать.
Вместо array of string используй TStringList.
А дальше обычное правило пересылки данных нефиксированной длины.
Сначала отправляешь 4 байта - размер данных, потом сами данные.
В твоём случае это 
Socket.SendBuf(Length(StringList.Text), 4);
Socket.SendBuf(StringList.Text[1], Length(StringList.Text) * SizeOf(char));
PM MAIL   Вверх
kami
Дата 18.4.2011, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 6
Всего: 72



Цитата(lux16 @  18.4.2011,  14:25 Найти цитируемый пост)
После отправки пишу такой код Application.ProccesMessages;

Это костыль. Причем плохой костыль.
PM MAIL WWW   Вверх
lux16
Дата 19.4.2011, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 10.8.2010

Репутация: нет
Всего: нет



Млин, помогите разобраться
PM MAIL   Вверх
Snowy
Дата 19.4.2011, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Сформируй весь текст через TStringList, потом возьми весь текст одной строкой - TStringList.Text.
Передай длину текста.
Передай сам текст.
Я уже дал 2 строки отправки.
Как принять:
Код

Socket.ReceiveBuf(len, 4);
SetLength(s, len);
Socket.ReceiveBuf(s[1], len * SizeOf(char));
StringList.Text := s;
где 
len: integer - длина текста в символах
s: string - строка, в которую принять текст.
StringList - результат, в который положить принятый текст.
Вместо StringList можешь использовать любой TStrings (например Memo1.Lines)
Как работать с TStrings/TStringList, надеюсь знаешь.
Ну и, как дополнительный совет - всю работу с сокетами помещай в try блок.
Ибо исключения при работе с сетью - обычное дело.

Добавлено через 8 минут и 38 секунд
Проще нарисовать...
Код

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
var
  sl: TStringList;
  len: integer;
begin
  sl := TStringList.Create();
  sl.Add('Строка №раз');
  sl.Add('А это вторая строка');
  sl.Add('Эта строка последняя!');
  sl.Add('Честное слово');
  sl.Add('А вот и нет! Я вас обманул!');
  try
    len := sl.Text.Length;
    Socket.SendBuf(len, SizeOf(len));
    Socket.SendBuf(sl.Text[1], len * SizeOf(char));
  finally
    sl.Free;
  end;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
  len:  Integer;
  s:    string;
begin
  try
    Socket.ReceiveBuf(len, SizeOf(len));
    SetLength(s, len);
    Socket.ReceiveBuf(s[1], len * SizeOf(char));
    Memo1.Lines.Text := s;
  finally
  end;
end;
Писал прямо в браузере - не проверял. Но ошибок вроде нет.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0616 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.