Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.31;
Скачать: CL | DM;

Вниз

TServerSocket   Найти похожие ветки 

 
Klopan   (2004-08-18 12:47) [0]

Как с помощью TClientSocket отправить структуру (или тип Pointer) на TServerSocket ?

например

type
 TMyrec = record
    s: string;
    i: integer;
    b: boolean;
 end;


 
Digitman ©   (2004-08-18 12:49) [1]

см. SendBuf()


 
Klopan ©   (2004-08-18 12:53) [2]

мне бы примерчик :)) плиз


 
Digitman ©   (2004-08-18 13:10) [3]

что непонятно ?


 
Klopan ©   (2004-08-18 17:14) [4]

...
TMyrec = record
   s: string;
   i: integer;
   sz: string;
end;
...
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var
 v: tmyrec;
begin
Socket.ReceiveBuf(v, sizeof(v));
listbox1.Items.Add(v.s);
listbox1.Items.Add(inttostr(v.i));
listbox1.Items.Add(v.sz);
end;
...
procedure TForm1.Button1Click(Sender: TObject);
var
 v: tmyrec;
begin
ClientSocket1.Active:= true;
with v do
begin
s:= "lala";
i:= 543;
sz:= "gfgfgf";
end;
if ClientSocket1.Socket.Connected then
ClientSocket1.Socket.SendBuf(v, sizeof(v));
//ClientSocket1.Active:= false;
end;

при приеме приходит только переменная i.
s и sz пустые.


 
Digitman ©   (2004-08-18 17:22) [5]


> Klopan ©   (18.08.04 17:14) [4]


это потому что ты не понимаешь разницы между статическими и динамическими строками

s и sz есть динамические строки, они представлены указателями, вот те самые указатели (а не то на что они указывают !) ты и передаешь/принимаешь


 
Klopan ©   (2004-08-18 17:30) [6]

я непонял :))
можно пример?

а i, это неуказатель?

я вообще незнал что такие бывают и непонимаю разницы между статическими и динамическими строками.


 
Klopan ©   (2004-08-18 18:11) [7]

дайте пожалуйста примерчик, plizz


 
Digitman ©   (2004-08-19 08:12) [8]


> а i, это неуказатель?


i - это не указатель

var k: Integer;
..
k := Length(v.s);
ClientSocket1.Socket.SendBuf(k, sizeof(k));
ClientSocket1.Socket.SendBuf(PChar(v.s)^, k);
ClientSocket1.Socket.SendBuf(i, sizeof(i));
k := Length(v.sz);
ClientSocket1.Socket.SendBuf(k, sizeof(k));
ClientSocket1.Socket.SendBuf(PChar(v.sz)^, k);


 
Digitman ©   (2004-08-19 08:12) [9]

Удалено модератором


 
Klopan ©   (2004-08-20 03:54) [10]

так как всетаки послать структуру, неразделяя ее данные?

(
var v: tmyrec;
sendbuf(v, sizeof(v));
)


 
Klopan ©   (2004-08-20 06:35) [11]

как я понял:
динамические строки - указатели
статические - неуказатели

как динамическую строку преобразовать в статическую или
как указатель преобразовать в неуказатель.

Зачем посылать переменную k ?

А если структура будет такой:
rec
ss: tstrings;
as: pansichar;
sd: string[30];
vr: variant;
ar: array[0..255] of Char;
end;


 
Klopan ©   (2004-08-20 06:36) [12]

Удалено модератором


 
Klopan ©   (2004-08-20 06:37) [13]

Удалено модератором


 
atruhin ©   (2004-08-20 07:42) [14]

>А если структура будет такой:
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


 
Digitman ©   (2004-08-20 08:33) [15]


> 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;


значения полей, помеченных как "указатель", посылать бессмысленно


 
имя   (2004-08-20 14:15) [16]

Удалено модератором


 
имя   (2004-08-20 14:16) [17]

Удалено модератором


 
имя   (2004-08-20 14:16) [18]

Удалено модератором


 
имя   (2004-08-20 14:18) [19]

Удалено модератором


 
имя   (2004-08-20 14:19) [20]

Удалено модератором


 
имя   (2004-08-20 14:21) [21]

Удалено модератором


 
Digitman ©   (2004-08-20 14:32) [22]

Удалено модератором


 
Klopan ©   (2004-08-20 20:41) [23]

а можно просто пример???
или исходник где используется структура.

или как отправить структуру

tmyrec = record
 vi: integer;
 vs: string;
 vb1, vb2: boolean;
end;

и как ее принять?

просто код.


 
Verg ©   (2004-08-21 14:02) [24]

Странно все это...
Тебе же вроде объясняли-объясняли, объясняли-объясняли, что эта структура содержит элемент типа pointer (по сути) - vs. И передавать его кому-либо в "сыром" виде бесполезно. Это как вместо файла передавать на другой компьютер полный путь до него на данном.
Вот давай я тебе вместо исходника программы передам строчку "E:\work\sources\sructsend.pas": Бери, не жалко, типа... :))

Ее все равно придется передавать трансформировав в инф. потоке в некую дургую структуру, в которой будет изложено содержание поля vs  и его (содержания) реальная длина. А на приемном конце эту структуру надо будет "собрать" обратно.


 
Bes   (2004-08-23 01:01) [25]

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;


 
atruhin ©   (2004-08-23 13:32) [26]

> я мучался с этим ужас как долго
Посмотри внимательно
Digitman ©   (19.08.04 08:12) [8]
чтоб не мучаться :)


 
Bes   (2004-08-23 23:04) [27]

2 atruhin:  а это не решение проблемы, там посылается каждая переменная в структуре по отдельности, а надо вместе ...


 
Verg ©   (2004-08-23 23:54) [28]


> [27] Bes   (23.08.04 23:04)



> а надо вместе ...


Как раз там все "вместе" передается. Все друг за другом. Безо всяких зазоров. :)
Или какое место имелось ввиду? В каком месте надо?


 
Bes   (2004-08-24 13:32) [29]

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 загнать в  структуру то тоды куль :)



 
Rouse_ ©   (2004-08-24 14:02) [30]

Вот тебе пример:

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;


 
Digitman ©   (2004-08-24 14:09) [31]


> 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 до тех пор пока все содержимое сформированного стрима не будет поставлено в очередь на передачу



Страницы: 1 вся ветка

Текущий архив: 2004.10.31;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.029 c
14-1097134424
Danilka
2004-10-07 11:33
2004.10.31
Все об админах :)


1-1097614029
quickblack
2004-10-13 00:47
2004.10.31
Как убрать картинку с иконки файла?


3-1096622628
vic1
2004-10-01 13:23
2004.10.31
Построение дерева


14-1097687498
Comp
2004-10-13 21:11
2004.10.31
Что-то я не пойму перевода


4-1096390666
hgd
2004-09-28 20:57
2004.10.31
Скажите как нажать кнопку в другой открытой программе