![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TServerSocket
Klopan © (2004-08-18 12:47:00)Как с помощью TClientSocket отправить структуру (или тип Pointer) на TServerSocket ?
например
type
TMyrec = record
s: string;
i: integer;
b: boolean;
end;
Digitman (2004-08-24 14:09:00) [1]
> Bes (24.08.04 13:32) [29]
> clientsocket.socket.sendbuf(r,sizeof(r)) // вот это я называю
> вместе...
во-первых,
нет никакого резона гонять по сети лишние (избыточные) байты - строка string[255] вполне может содержать единственный инф.символ (самый первый), остальные правые 254 - бестолковые пробелы; передавая же ту же самую инф-цию, но послав сначала 4 байта длины, а затем 1 байт собственно значащих данных, ты передашь ту же самую инф-цию, но в 51 раз меньшего объема.. траффик-то как правило не резиновый ! да и пропускная способность сет.соединений может накладывать существ.ограничения ...
во-вторых,
> мона будет одим readbufferom загнать в структуру
в общем случае полагаться на это нельзя - может потребоваться N вызовов readbuffer(), чтобы суммарный объем принятых данных соответствовал по размеру единственной посланной передатчиком структуры sendbuf(r,sizeof(r))
в-третьих,
все вроде бы замечательно, когда режим гнезда передатчика - блокирующий, но не следует полагаться на то, что при неблок.режиме передатчику для передачи целиком той же структуры потребуется всего один вызов sendbuf() - их может потребоваться более одного .. в этом случае алгоритм значительно упрощается, если структуру в том или ином виде сначала записать в стрим, а затем вызвать SendStream(стрим), при этом передатчик автоматически и прозрачно для тебя задействует механизм обработки события On[Client]Write до тех пор пока все содержимое сформированного стрима не будет поставлено в очередь на передачу
Rouse_ (2004-08-24 14:02:00) [2]Вот тебе пример:
procedure TForm1.FormCreate(Sender: TObject);
var
Buffer: array of byte;
Rec1, Rec2: Trec;
begin
Rec1.s := 'test';
Rec1.i := 100;
rec1.b := True;
SetLength(Buffer, Sizeof(Trec));
// Отправили в буффер
Move(Rec1, Buffer[0], Sizeof(Trec));
// Теперь можно делать с ним все что угодно, к примеру отправлять по сети
// А теперь получаем данные из буффера
Move(Buffer[0], Rec2, Sizeof(Trec));
// Проверка
if Rec2.b then Caption := Rec2.s;
end;
Bes (2004-08-24 13:32:00) [3]2 verg
смотри
Trec=record
s:string[255];
i:integer;
b:boolean;
end;
Trec1=record
s:string;
i:integer;
b:boolean;
end;
...
var
r:trec;
r1:Trec;
...
clientsocket.socket.sendbuf(r,sizeof(r)) // вот это я называю вместе...
....
clientsocket.socket.sendbuf(r1,sizeof(r1)) //вот так не пешлется ;)
...
вот это раздельно...
clientsocket.socket.sendbuf(r.s,length(s));
clientsocket.socket.sendbuf(r.b,sizeof(b));
clientsocket.socket.sendbuf(r.i,sizeof(i));
хотя если при принятии все эти пакетики мона будет одим readbufferom загнать в структуру то тоды куль :)
Verg (2004-08-23 23:54:00) [4]
> [27] Bes (23.08.04 23:04)
> а надо вместе ...
Как раз там все "вместе" передается. Все друг за другом. Безо всяких зазоров. :)
Или какое место имелось ввиду? В каком месте надо?
Bes (2004-08-23 23:04:00) [5]2 atruhin: а это не решение проблемы, там посылается каждая переменная в структуре по отдельности, а надо вместе ...
atruhin (2004-08-23 13:32:00) [6]> я мучался с этим ужас как долго
Посмотри внимательно
Digitman © (19.08.04 08:12) [8]
чтоб не мучаться :)
Bes (2004-08-23 01:01:00) [7]tmyrec = record
vi: integer;
vs: string;
vb1, vb2: boolean;
end;
такую структуру не удастаться передать, я мучался с этим ужас как долго (если кто знает пусть расскажет очень буду признателен).
а вся проблема как уже сказано в переменной vs.
потому что она указывает не на данные, а на место в памяти..
чтобы в этом до конца убедится... сделай так
var
s1:string;
s2:string[255];
begin
showmessage(sizeof(s1)); //здесь будет 4
showmessage(sizeof(s2));//здесь будет 256
end;
s1 - просто указатель,а указатель это "числовая" переменная занимающая 4 байта (как тип Longint) и не хранящая никаких данных.
s2 - это конктретные данные
она показывает компутеру откуда начинается строка
если чуток трасформировать твою струтуру в
tmyrec = record
vi: integer;
vs: string[255];
vb1, vb2: boolean;
end;
то все будет чики пики...
отослать вот так
var
data:Tmyrec;
begin
...
ClientSocket1.Socket.SendBuf(data,sizeof(tmyrec));
end;
а принять типа
type
...
PMyrec=^tmyrec;
procedure Tform1.SocketServerOnReceive(...);
var
data:PMyrect;
begin
new(data);
ServerSocket.readbuffer(data^,sizeof(TmyRec));
...
..
dispose(data)
end;
Verg (2004-08-21 14:02:00) [8]Странно все это...
Тебе же вроде объясняли-объясняли, объясняли-объясняли, что эта структура содержит элемент типа pointer (по сути) - vs. И передавать его кому-либо в "сыром" виде бесполезно. Это как вместо файла передавать на другой компьютер полный путь до него на данном.
Вот давай я тебе вместо исходника программы передам строчку "E:\work\sources\sructsend.pas": Бери, не жалко, типа... :))
Ее все равно придется передавать трансформировав в инф. потоке в некую дургую структуру, в которой будет изложено содержание поля vs и его (содержания) реальная длина. А на приемном конце эту структуру надо будет "собрать" обратно.
Klopan (2004-08-20 20:41:00) [9]а можно просто пример???
или исходник где используется структура.
или как отправить структуру
tmyrec = record
vi: integer;
vs: string;
vb1, vb2: boolean;
end;
и как ее принять?
просто код.
Digitman (2004-08-20 14:32:00) [10]Удалено модератором
(2004-08-20 14:21:00) [11]Удалено модератором
(2004-08-20 14:19:00) [12]Удалено модератором
(2004-08-20 14:18:00) [13]Удалено модератором
(2004-08-20 14:16:00) [14]Удалено модератором
(2004-08-20 14:16:00) [15]Удалено модератором
(2004-08-20 14:15:00) [16]Удалено модератором
Digitman (2004-08-20 08:33:00) [17]
> Klopan © (20.08.04 06:36) [12]
> как я понял:
> динамические строки - указатели
> статические - неуказатели
не так ты понял
переменная типа "длинная строка" (читай - string или ansistring) хранит не сами сторковые данные, а 4-байтный указатель на упр.структуру в адресном пространстве текущего процесса, а уж в этой структуре хранится сч-к ссылок на строку, длина строки и адрес собственно строковых данных .. память под то на что указывает этот указатель выделяется динамически на этапе работы программы ... бессмысленно передавать этот 4-байтный указатель в адр.пр-во другого процесса
переменная типа "короткая строка" (читай - string[] или shortstring) хранит собственно строковые данные, память под эту переменную выделяет компилятор на этапе компиляции проекта
> А если структура будет такой:
> rec
> ss: tstrings; //указатель
> as: pansichar; //указатель
> sd: string[30]; //собственно данные
> vr: variant; //указатель
> ar: array[0..255] of Char; //собственно данные
> end;
значения полей, помеченных как "указатель", посылать бессмысленно
atruhin (2004-08-20 07:42:00) [18]>А если структура будет такой:
ss:tstrings; - это указатель на объект.
as : pansichar - указатель на char;
>Зачем посылать переменную k ?
переменная k посылается чтобы во входном потоке данных ты мог определить длинну строки.
Как вариант можно отправить так:
ClientSocket1.Socket.SendBuf(PChar(v.s)^, Length(v.s)+1);
ClientSocket1.Socket.SendBuf(v.i, sizeof(v.i));
ClientSocket1.Socket.SendBuf(PChar(v.sz)^,Length(v.sz)+1);
тогда окончание строки получишь как #0
Klopan (2004-08-20 06:37:00) [19]Удалено модератором
Klopan (2004-08-20 06:36:00) [20]Удалено модератором