Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 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
1-93572
Фагот
2004-01-19 09:52
2004.01.29
Текстовый файл


3-93390
pashtet
2003-12-30 14:13
2004.01.29
TtreeView


1-93564
Xmen
2004-01-17 10:56
2004.01.29
Ввод данных


3-93395
Прямой
2004-01-05 12:22
2004.01.29
ADOQuery ругается


3-93406
NailMan
2004-01-05 09:33
2004.01.29
База для Media Library видеоплеера





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский