-
krupt (27.01.13 22:34) [0]WinXP, RAD 2009.
Доброй ночи, вечера, дня!
Сейчас принимаю сообщения так:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
s, r: WideString;
begin
try
AContext.Connection.IOHandler.CheckForDisconnect(True, True);
if AContext.Connection.Connected then
begin
s := AContext.Connection.Socket.ReadLn(enUTF8);
............................ // Делаем чего-то
AContext.Connection.Socket.WriteLn(_r, GetEncoding);
end;
except
on E: Exception do
begin
if E.ClassType <> EIdConnClosedGracefully then
if E.ClassName <> 'EIdNotConnected' then
if E.ClassName <> 'EIdClosedSocket' then
ShowMessage(E.ClassName + ': ' + E.Message);
end;
end;
end;
Т.е. через ReadLn
А хочется сделать следующее.
Во входящем сообщении будет приходить 2 символа с указанием длины сообщения.
Необходимо сначала прочитать первые два символа сообщения, не удаляя из стека сообщение. Посчитать длину сообщения и считать сообщение с указанной длинной. Удалить сообщение из стека.
Подскажите, пож-та, как можно реализовать такое.
Спасибо. -
krupt (27.01.13 22:36) [1]Возможно ли такое через Indy? Или нужно сделать через что-то другое?
-
Сергей М. © (27.01.13 23:10) [2]Для посимвольного чтения буфера предназначен метод Connection.Socket.ReadChar
Важно только понимать что в юникодовой версии символ двухбайтовый. -
krupt (28.01.13 19:02) [3]Думаю, что это немножко не то.
Есть функцияAContext.Connection.Socket.ReadString(AButes: Integer; [encoding])
Вот это работает как нужно в плане количества считывания символов.
Но после первого считывания стэк очищается и повторно прочитать сообщение нельзя. Может я чего то неправильно делаю? -
Сергей М. © (28.01.13 21:36) [4]
> стэк очищается и повторно прочитать сообщение нельзя
> Может я чего то неправильно делаю?
Не то что делаешь - думаешь неправильно. -
krupt (29.01.13 08:46) [5]Возможно, я не правильно выражаюсь. Не стэк, а входящая очередь.
Я видел где-то, что можно прочитать сообщение без удаления из входящей очереди. А по умолчанию считывается с удалением.
Подскажите, пож-та, как такое делается в Indy. Спасибо. -
Сергей М. © (29.01.13 09:05) [6]Поясни зачем тебе понадобилось читать сообщение без удаления из очереди ..
-
krupt (29.01.13 09:11) [7]Считываю некое-количество символов.
Получаю из них длину сообщения.
Считываю сообщение полностью. -
Сергей М. © (29.01.13 12:04) [8]Ты не ответил на вопрос зачем это делать без удаления из очереди ..
-
krupt (29.01.13 12:43) [9]Как иначе точно определить размер сообщения?
Ведь если вызвать ReadString с большим числом, чем число символов, то поток будет "висеть" пока не накопится достаточное кол-во символов. -
Сергей М. © (29.01.13 12:55) [10]
> Как иначе точно определить размер сообщения?
Ну ты же сам сказал что размер сообщения у тебя передается в первых двух символах сообщения ?
Вот первые два символа и читай.
> поток будет "висеть"
и что ?
дополнительный пусть себе висит.
а основной можно либо размораживать средствами IdAntifreeze либо предусматривать фиксированный ReadTimeout нужного малого размера -
krupt (29.01.13 13:09) [11]Вот прочитал я первые два символа. Определил длину сообщения.
А дальше что делать? -
Сергей М. © (29.01.13 13:39) [12]А дальше читай сообщение этой длины.
-
krupt (29.01.13 14:06) [13]Дак собственно, когда пытаюсь прочитать, то получаю кукиш.
L := AContext.Connection.Socket.ReadString(2, enUTF8);
ShowMessage(L);
M := AContext.Connection.Socket.ReadString(StrToInt(L), enUTF8);
ShowMessage(M);
В L загружается 2 первый символа, а M пустая строка. -
Сергей М. © (29.01.13 14:18) [14]
> В L загружается 2 первый символа
И как выглядит их содержимое ?
То что ты видишь соответствует тому что ты передал ? -
krupt (29.01.13 15:03) [15]Да, соотвествует.
-
Сергей М. © (29.01.13 15:06) [16]Покажи код передачи ..
-
krupt (30.01.13 11:03) [17]
IdTCPClient1.Connection.Socket.WriteLn(Edit1.Text, enUTF8); -
Сергей М. © (30.01.13 17:26) [18]И где тут передача префикса 2-х символов с информацией о длине строкового сообщения ?
-
krupt (30.01.13 17:36) [19]В Edit1.Text сам вписываю. Я ведь пока тестирую. Поэтому сильно код не нагромождаю.