Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Закрытая тема
Ваша тема закрыта, почему это могло произойти? Возможно,
Нет наработок или кода, если нужно готовое решение - создайте тему в разделе Фриланс и оплатите работу.
Название темы включает слова - "Помогите", "Нужна помощь", "Срочно", "Пожалуйста".
Название темы слишком короткое или не отражает сути вашего вопроса.
Тема исчерпала себя, помните, один вопрос - одна тема
Прочитайте правила и заново правильно создайте тему.
 
Опции темы Поиск в этой теме
Старый 04.09.2009, 11:06   #1
VaBank
Пользователь
 
Аватар для VaBank
 
Регистрация: 26.05.2009
Сообщений: 26
По умолчанию Послать/принять динамический Record через сокеты

Здравствуйте!
Мне нужна Ваша помощь. Я не могу понять, как передать динамическую структур через сокет. Пример:
Код:
TArray_Data = packed record
	fText_a: String[50];
end;
...
var
  Form1: TForm1;
  fData: array of TArray_Data;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
SetLength(fData, 2);
fData[0].fText_a:='Первая строка';
fData[1].fText_a:='Вторая строка';
ClientSocket1.Socket.SendBuf(fData, SizeOf(fData));
end;
Принимаю:
Код:
TArray_Data = packed record
	fText_a: String[50];
end;
...
var
  Form1: TForm1;
  fData: array of TArray_Data;
...
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var i: Cardinal;
begin
i:=Socket.ReceiveLength;
SetLength(fData, i);
for i := 0 to ??? do begin
  Memo1.Lines.Add(fData[i].fText_a);
end;
end;
Короче этот способ в корне неверный для передачи/приема динамической структуры. Во первых SizeOf я так понимаю тут непригоден, во-вторых при приеме я не понимаю сколько элементов в массиве.
Ну короче запар. Думал как с MemoryStream делать, чего-то еще хуже, ваще ничего непашет, да и не работал я особо с мемористрим. Может кто подскажет КОДОМ что делать?
VaBank вне форума
Старый 04.09.2009, 12:09   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Я бы наверное передавал через Stream...

Впрочем можно попробовать структуру пихнуть в Стринг:
Код:
var a:TArray_Data;   s:string;
begin 
 ZeroMemory(@a,sizeof(a));
 a.fText_a:='123';
 a.fText_b:='qwe';
 SetLength(s,sizeof(a));
 Move(a,s[1],length(s));
end;
И Уже s передавать в сокет. А приняв провести обратную развертку.
I'm learning to live...
Stilet вне форума
Старый 04.09.2009, 12:22   #3
VaBank
Пользователь
 
Аватар для VaBank
 
Регистрация: 26.05.2009
Сообщений: 26
По умолчанию

Ну эту структуру я привел для примера. На самом деле у меня будет много инфы и структура примерно такая:
Код:
TInfoData = packed record
    fCommandData: Integer;
    fIP: String[15];
    fIPADDR: String[60];
    fIPNamePlace: String[30];
    fIPRemark: String[100];
    fReaction: String[1];
    fSensorName: String[2];
    fSensorNum: Integer;
    fSensorTime: Integer;
    fSensorTimeEnd: TDateTime;
    fSensorDate: String[23];
    fModuleTimeFromOn: Integer;
    fSensorDescript: String[30];
    fSensorNamePlace: String[30];
    fSensorRemark: String[100];
    fState: Integer;
    fGUIDName: String[38];
    fGUIDState: boolean;
    fTimeOutDelete: String[3];
    fTimeOutShowWarning: String[3];
    fErrorMessage: String[255];
  end;
...
var
    TempInfoData1,
    TempInfoData2: array of TInfoData;
В виде строки это как не то, да данные мне кажется потеряются. Кстати я использую блокирующие сокеты. Тут просто для примера по UDP спросил.
VaBank вне форума
Старый 04.09.2009, 12:38   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
В виде строки это как не то
А по мне так норм. Строка все рамно что массив.
Цитата:
да данные мне кажется потеряются.
С чего бы? Если вся строка передалась и принялась то нет.

Впрочем ты всегда можешь передать потоком.
I'm learning to live...
Stilet вне форума
Старый 04.09.2009, 12:57   #5
VaBank
Пользователь
 
Аватар для VaBank
 
Регистрация: 26.05.2009
Сообщений: 26
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Я бы наверное передавал через Stream...

Впрочем можно попробовать структуру пихнуть в Стринг:
Код:
var a:TArray_Data;   s:string;
begin 
 ZeroMemory(@a,sizeof(a));
 a.fText_a:='123';
 a.fText_b:='qwe';
 SetLength(s,sizeof(a));
 Move(a,s[1],length(s));
end;
И Уже s передавать в сокет. А приняв провести обратную развертку.
а где объявлена S? Кстати как принять?
VaBank вне форума
Старый 04.09.2009, 13:13   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Я давно с сокетами не возился...
Все еще проще чем ты думаешь:
Вот посылка структуры :
Код:
type
TArray_Data = packed record
	fText_a: String[50];
        a:integer;
        b:double;
end;

procedure TForm1.Button1Click(Sender: TObject);
var q:TArray_Data;s:string;
begin
 q.fText_a:='stringers';
 q.a:=33;
 q.b:=23.6;
 ClientSocket1.Socket.SendBuf(q,Sizeof(q));
end;
а вот ее чтение:
Код:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var e:TArray_Data;
begin
 Socket.ReceiveBuf(e,SizeOf(e));
 caption:=e.fText_a;
end;
Тут ничего приводить не нужно.
I'm learning to live...
Stilet вне форума
Старый 04.09.2009, 13:45   #7
VaBank
Пользователь
 
Аватар для VaBank
 
Регистрация: 26.05.2009
Сообщений: 26
По умолчанию

Это посылка статического Record. Напомню, изначально вопрос был в том как послать динамический Record, т.е. не
var e:TArray_Data;
а
var e:array of TArray_Data;
Когда неизвестно заранее кол-во элементов, да еще это количество надо знать как-то где принимаешь эту структуру...
VaBank вне форума
Старый 04.09.2009, 16:29   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

формрируем пакет типа того:
[кол-во записей]{сами записи}
я думаю понятно?
в поток пихнуть это просто все
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума
Старый 04.09.2009, 16:39   #9
VaBank
Пользователь
 
Аватар для VaBank
 
Регистрация: 26.05.2009
Сообщений: 26
По умолчанию

Зашел на форму спросить как сделать....понятно...буду по другим форумам вопросы задавать.
Идею я и сам понимаю, как это кодом организовать...
VaBank вне форума
Старый 30.07.2015, 08:37   #10
alecha99
 
Регистрация: 26.05.2015
Сообщений: 4
По умолчанию

У вас каждая запись с фиксированным размером. Всё просто запихиваете весь динамический массив TmemoryStream как есть и посылаете сжатым бинарником, на втором конце разжимаете и считываете в record необходимое число байт на каждую запись. Сложнее всего когда каждая запись предполагает массивы значений)
alecha99 вне форума
Закрытая тема


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
передачи файлов через сокеты CHITER Работа с сетью в Delphi 5 09.07.2010 21:55