Форум: "Сети";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.032 c