Форум: "Сети";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];
ВнизНепонятная проблема с буфером в Инди компоненте Найти похожие ветки
← →
h0use (2003-11-24 15:32) [0]Есть сервер, который слушает порт:
Msg:=AThread.Connection.ReadLn;
if Msg<>">>>" then exit;
AThread.Connection.ReadBuffer(CommBlock,SizeOf(CommBlock));
Есть клиент, котрый шлет на сервер блок данных:
function TfmMain.SendMsg(AMsg:TCommBlock): boolean;
begin
Result:=False;
try
if TCPClient.Connected then
begin
TCPClient.WriteLn(">>>");
TCPClient.WriteBuffer(AMsg,SizeOf(AMsg));
Result:=True;
end;
except
on e: Exception do
ShowMessage("Send Error: "+e.Message);
end; // try/except
Есть сам покет данных одинаковый для сервера и клиента:
type
TCommBlock = record // the Communication Block used in both parts (Server+Client)
Command : Char;
Argument1 : String[10];
Argument2 : WideString;
Msg : WideString;
end;
При том, что при дебаге клиент шлет нормальную инфу, сервер получает тольуо первый и второй аргумент записи нормально, а третий и четвертый - белеберда. В чем ботва?
← →
Reindeer Moss Eater (2003-11-24 15:36) [1]Эти аргументы - указатели.
На сервере они так же полезны, как и седло корове
← →
h0use (2003-11-24 15:48) [2]Т.е. ты хочешь сказать, что char и string передается как есть, а widestring передается как указатель?
← →
Reindeer Moss Eater (2003-11-24 15:49) [3]Он и есть указатель.
http://delphimaster.net/view/6-1069393748/
← →
Digitman (2003-11-24 15:53) [4]
> h0use
ansistring и widestring - да, как указатели ... почему тебя это шокирует ?
← →
h0use (2003-11-24 15:58) [5]А как же мне их передавать?
← →
Reindeer Moss Eater (2003-11-24 15:59) [6]А зачем передавать ИХ?
← →
Reindeer Moss Eater (2003-11-24 16:00) [7]А ссылка для кого вообще приведена была?
← →
Digitman (2003-11-24 16:05) [8]
> h0use
> как же мне их передавать
как компилятор хранит - так и передавай : сначала размер, потом данные
← →
h0use (2003-11-24 16:27) [9]Если честно, то я слабо понял, что там происходит (в примере по ссылке)
← →
Reindeer Moss Eater (2003-11-24 16:29) [10]Тогда просто замени свои WideString на ShortString
← →
Digitman (2003-11-24 16:35) [11]
> я слабо понял
это печально
и не поймешь, пока не бросишь слепые эксперименты и не обратишься к соотв.литературе ... либо не начнешь задавать КОНКРЕТНЫЕ вопросы, мол, объясните . почему это именно так , а не иначе
← →
sanya-spb (2003-11-24 16:49) [12]как вариант может и PChar сойти.. я так думаю
← →
Reindeer Moss Eater (2003-11-24 16:51) [13]В качестве того же указателя, но "в профиль" ?
← →
h0use (2003-11-24 16:56) [14]Делаю вот так:
GetMem(p,SizeOf(Char)+3*SizeOf(Cardinal)+StrLen(AMsg.Argument1)+StrLen(AMsg.Argument2)+StrLen(AMsg.Msg));
pC:=p;
pC^:=AMsg.Command;
Inc(pC);
pLen1 := Pointer(pC);
pLen1^:=StrLen(AMsg.Argument1);
Inc(PLen1);
StrCopy(PChar(PLen1),AMsg.Argument1);
pLen2 := Pointer(pLen1);
pLen2^:=StrLen(AMsg.Argument2);
Inc(PLen2);
StrCopy(PChar(PLen1),AMsg.Argument2);
pLen3 := Pointer(pLen2);
pLen3^:=StrLen(AMsg.Msg);
Inc(PLen3);
StrCopy(PChar(PLen1),AMsg.Msg);
TCPClient.WriteLn(">>>");
TCPClient.WriteBuffer(p^,SizeOf(Char)+3*SizeOf(Cardinal)+StrLen(AMsg.Argument1)+StrLen(AMsg.Argument2)+StrLen(AMsg.Msg)) ;
Result:=True;
Пришлось поменять в структуре все виды срок на PChar, так как я не додумался как адаптировать пример по ссылке под widestring, но все равно не работает!
← →
sanya-spb (2003-11-24 17:05) [15]а зачем тебе так надо открытые строки использовать?
неужели нельзя ShortString взять?
если нельзя то можно заменить строку на StringStream или нечто подобное...
← →
h0use (2003-11-24 17:14) [16]Впринципе логично, можно и не использовать...буду думать дальше...
← →
Reindeer Moss Eater (2003-11-24 17:17) [17]//Распределил память под сообщение
GetMem(p,SizeOf(Char)+3*SizeOf(Cardinal)+StrLen(AMsg.Argument1)+StrLen(AMsg.Argument2)+StrLen(AMsg.Msg));
//Записал символ команды
pC:=p;
pC^:=AMsg.Command;
Inc(pC);
//После символа команды записал длину первого аргумента
pLen1 := Pointer(pC);
pLen1^:=StrLen(AMsg.Argument1);
//После длины первого аргумента записал строку первого аргумента
Inc(PLen1);
StrCopy(PChar(PLen1),AMsg.Argument1);
//Встал на начало строки первого аргумента
pLen2 := Pointer(pLen1);
//Испортил первые четыре символа строки первого аргумента, записав поверх их длину второго аргумента
pLen2^:=StrLen(AMsg.Argument2);
Inc(PLen2);
//Перешагнул через испорченные 4 первых байта строки первого аргумента и записал строку второго аргумента (поверх еще неиспорченных символов строки первого аргумента)
StrCopy(PChar(PLen1),AMsg.Argument2);
....
Ну и так далее
← →
h0use (2003-11-25 16:01) [18]Ну так а как сделать правильно?
← →
Reindeer Moss Eater (2003-11-25 16:07) [19]Очевидно, что правильно будет тогда, когда не будешь на очередном шаге портить содержимое памяти созданное предыдущим шагом.
А вообще тот конкретный пример был дан как иллюстрация передачи конкретной структуры. Её не предлагалось изменить, а была предложена подпорка, которая умеет передавать данные той первоначальной структуры.
← →
h0use (2003-11-25 16:57) [20]Ну так объясните, плиз, если у меня конструкция
TCommBlock = packed record
Command : Byte;
Argument1 : Byte;
Argument2 : Byte;
Msg : String;
end;
И почему при аналогичной структуре в примерах Инди все работает без ухищрения с указателями?
← →
Reindeer Moss Eater (2003-11-25 17:04) [21]Потому что там компилятор считает Msg короткой строкой.
← →
h0use (2003-11-25 17:06) [22]т.е. если я напишу String[255] то все заработает?
← →
h0use (2003-11-25 17:09) [23]И заработало! Блин, но так не честно! Нигде в хелпе по Делфе это не написано, а я угробил сутки для понимания проблемы :(
← →
h0use (2003-11-25 17:09) [24]Забыл поблагодарить за помощь!
← →
Reindeer Moss Eater (2003-11-25 17:11) [25]Что "все"?
У тебя и так все работает.
Все что ты просишь у компилятора.
Он создает отличный код, который передает ВСЕ, что ты его просишь передать (все до единого бита)
И пора понять, что есть короткие строки, все символы которых лежат внутри записи, и есть длинные строки, которые находятся в куче. И куча эта располагается далеко за пределами всех сегментов твоей программы (кода,данных,стека)
← →
h0use (2003-11-25 17:19) [26]Просто провал в образовании, я всегда считал, что если у строки не указано кол-во символов, то это эквивалентно строке 255 символов т.е. String=String[255]. Оказалось что заблуждался, хоть и в хелпе не нашел информации.
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c