-
Добрый вечер,
С помощью компоненты TcpClient необходимо прочитать данные переменной длины. Символ конца даных не определен и не используется и при использовании метода Receiveln, как показано ниже, программа подвисает.
var s: String; begin s := TcpClient1.Receiveln ... end;
Пробовал задавать Receiveln(#10), но тогда читается какой-то кусок пришедших данных и все.
Прошу посоветуйте, как разрешить или обойти данную заковырькю!
-
используй ReadBuffer
-
> Символ конца даных не определен
Кем не определен ?
> Пробовал задавать Receiveln(#10)
Почему именно #10, если "не определен" ?
-
Receiveln - принимает строковые переменные в формате ASCII. Если надо передать данные передавай через потоки, предварительно передав(и убедившись в получении приемной стороной) размер потока.
-
...или через буфер - CrytoGen (25.08.09 19:38) [1]
-
> Receiveln - принимает строковые переменные в формате ASCII.
Что за отсебячина ?
Справка гласит:
Reads delimited lines of data from the socket.
Delphi syntax:
function Receiveln(eol: string = CRLF): string;
Description
Receiveln reads a delimited chunk of data from the socket. The delimeter cannot be part of the character set. Receiveln fills the buffer until it reaches the delimeter.
Где здесь хоть какой-либо намек на "формат ASCII" ?
-
> Сергей М. (02.09.2009 10:56:05) [5]
Намек есть
function Receiveln(eol: string = CRLF): string;
Более того функция обязана реагировать и на другие управляющие символы, например на #0 и EOF
-
> функция обязана реагировать и на другие управляющие символы, > например на #0 и EOF
Не обязана. Взгляни на реализацию.
-
> Сергей М. (02.09.2009 11:39:07) [7]
Должна, но не обязана :-) Это нечестная строковая функция, значит придется придумывать механизм реализации EOF.
-
> Это нечестная строковая функция
Настолько же нечестная, насколько и TCustomWinSocket.ReceiveText .. )
> придется придумывать механизм реализации EOF
Нафих он тут нужен ?)
-
> Сергей М. (02.09.2009 14:22:09) [9]
Для реализации потоковых функций, когда конец потока строк неопределен. Если функция текста не умеет работать с символом EOF, то придется придумывать навесной протокол для ее реализации. По умолчанию файловые потоки строк обязаны реагировать на CR, LF, EOF и некоторые другие символы управления потоком, вне зависимости есть ли обратный канал.
-
> Anatoly Podgoretsky © (02.09.09 14:38) [10]
> когда конец потока строк неопределен
Он не может быть неопределен, иначе это не протокол, а фуфло) На чем я и заострил внимание автора. EOF - значит EOF, NULL - значит NULL, прочий символ или комбинация символов - значит они самые, НО нельзя при этом говорить что "символ конца данных не определен". Как же он, спрашивается, неопределен, если передатчик исправно терминирует строки в передаваемом им потоке в соответствии с неким утвержденным протоколом ? А то что автор не знает соглашений этого протокола или они ему попросту фиолетовы, вовсе не говорит о какой бы то ни было "неопределенности", кроме оной в голове автора)
-
> Сергей М. (02.09.2009 14:49:11) [11]
Ты рассказываешь про побочные эффекты данного компонента и не готов абстрагироваться от них.
-
> Anatoly Podgoretsky © (02.09.09 15:13) [12]
Да не у него никаких "побочных эффектов")
Что упрощен он - это да, я согласен. Можно было бы предусмотреть и множество терминаторов вместо одного. Ну, скажем, так:
function ReceiveLn(TermSet: array of string): String; overload; .. ReceiveLn([CR, LF, CRLF, EOF, #0, 'Черт те что и сбоку бантик']);
Но и в этом случае и в случае с ReceiveLn без параметров (т.е. по дефолту терминатор = CRLF) я знаю, что мой партнер в соответствии с неким утвержденным и известным нам обоим протоколом обязан терминировать передаваемые им в потоке строки одним из ожидаемых мной символов или последовательностью. Разве при этом можно утверждать, что признак конца строки не определен ?)
-
> Сергей М. (02.09.2009 15:56:13) [13]
Если бы не называли ReceiveLN то и претензий бы не было.
-
> Anatoly Podgoretsky © (02.09.09 16:03) [14]
У меня-то претензии не к компоненту и не к тому как в нем обозвали метод, а к формулировке вопроса:
> Символ конца даных не определен и не используется и при > использовании метода Receiveln, > как показано ниже, программа подвисает
1. Если ReceiveLn вызван без параметров, то это не означает что символ не определен и не используется - он попросту явно не указан, что подразумевает осознанное CRLF, т.е. от партнера мы ожидаем в качестве разделителя именно CRLF и ничто иное.
2. Последующие пляски с бубном
> Пробовал задавать Receiveln(#10)
говорят о том, что автор ни сном ни духом не ведает про соглашения о термирнировании строк, используемые партнером по соединению. А именно с изучения оных и следовало начать, прежде чем начинать заниматься научным тыком)
3. Receiveln не может подвешивать вызывающий поток, если не используется режим bmBlocking, а о режиме автор, кстати, упомянуть не удосужился.
4. В режиме bmNonBlocking при получении результатом вызова ReceiveLn пустой строки потребуются дополнительные телодвижения для определения причин такого результата - то ли партнер действительно послал пустую строку с ожидаемым терминатором, то ли он чего-от там послал, но еще не все пришло, то ли он вообще еще нишиша не посылал, то ли соединение корректно закрыто партнером
-
> Сергей М. (02.09.2009 16:33:15) [15]
Если по формулировке, то если "Символ конца даных не определен", то метод будет висеть до скончания века или разрыва соединения.
-
Подождем автора)
-
> Сергей М. (03.09.2009 09:29:17) [17]
C ним проблемы.
|