![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Подвисание при вызове TcpClient1.Receiveln() [WinXP]
alik © (2009-08-25 19:33:00)Добрый вечер,
С помощью компоненты TcpClient необходимо прочитать данные переменной длины. Символ конца даных не определен и не используется и при использовании метода Receiveln,
как показано ниже, программа подвисает.
var
s: String;
begin
s := TcpClient1.Receiveln
...
end;
Пробовал задавать Receiveln(#10), но тогда читается какой-то кусок пришедших данных и все.
Прошу посоветуйте, как разрешить или обойти данную заковырькю!
Anatoly Podgoretsky (2009-09-03 09:58:00) [1]> Сергей М. (03.09.2009 09:29:17) [17]
C ним проблемы.
Сергей М. (2009-09-03 09:29:00) [2]Подождем автора)
Anatoly Podgoretsky (2009-09-03 09:12:00) [3]> Сергей М. (02.09.2009 16:33:15) [15]
Если по формулировке, то если "Символ конца даных не определен", то метод будет висеть до скончания века или разрыва соединения.
Сергей М. (2009-09-02 16:33:00) [4]
> Anatoly Podgoretsky © (02.09.09 16:03) [14]
У меня-то претензии не к компоненту и не к тому как в нем обозвали метод, а к формулировке вопроса:
> Символ конца даных не определен и не используется и при
> использовании метода Receiveln,
> как показано ниже, программа подвисает
1. Если ReceiveLn вызван без параметров, то это не означает что символ не определен и не используется - он попросту явно не указан, что подразумевает осознанное CRLF, т.е. от партнера мы ожидаем в качестве разделителя именно CRLF и ничто иное.
2. Последующие пляски с бубном
> Пробовал задавать Receiveln(#10)
говорят о том, что автор ни сном ни духом не ведает про соглашения о термирнировании строк, используемые партнером по соединению.
А именно с изучения оных и следовало начать, прежде чем начинать заниматься научным тыком)
3. Receiveln не может подвешивать вызывающий поток, если не используется режим bmBlocking, а о режиме автор, кстати, упомянуть не удосужился.
4. В режиме bmNonBlocking при получении результатом вызова ReceiveLn пустой строки потребуются дополнительные телодвижения для определения причин такого результата - то ли партнер действительно послал пустую строку с ожидаемым терминатором, то ли он чего-от там послал, но еще не все пришло, то ли он вообще еще нишиша не посылал, то ли соединение корректно закрыто партнером
Anatoly Podgoretsky (2009-09-02 16:03:00) [5]> Сергей М. (02.09.2009 15:56:13) [13]
Если бы не называли Receive LNто и претензий бы не было.
Сергей М. (2009-09-02 15:56:00) [6]
> Anatoly Podgoretsky © (02.09.09 15:13) [12]
Да не у него никаких "побочных эффектов")
Что упрощен он - это да, я согласен. Можно было бы предусмотреть и множество терминаторов вместо одного.
Ну, скажем, так:
function ReceiveLn(TermSet: array of string): String; overload;
..
ReceiveLn([CR, LF, CRLF, EOF, #0, 'Черт те что и сбоку бантик']);
Но и в этом случае и в случае с ReceiveLn без параметров (т.е. по дефолту терминатор = CRLF) я знаю, что мой партнер в соответствии с неким утвержденным и известным нам обоим протоколом обязан терминировать передаваемые им в потоке строки одним из ожидаемыхмной символов или последовательностью.
Разве при этом можно утверждать, что признак конца строки не определен ?)
Anatoly Podgoretsky (2009-09-02 15:13:00) [7]> Сергей М. (02.09.2009 14:49:11) [11]
Ты рассказываешь про побочные эффекты данного компонента и не готов абстрагироваться от них.
Сергей М. (2009-09-02 14:49:00) [8]
> Anatoly Podgoretsky © (02.09.09 14:38) [10]
> когда конец потока строк неопределен
Он не может быть неопределен, иначе это не протокол, а фуфло)
На чем я и заострил внимание автора.
EOF - значит EOF, NULL - значит NULL, прочий символ или комбинация символов - значит они самые, НО нельзя при этом говорить что "символ конца данных не определен".
Как же он, спрашивается, неопределен, если передатчик исправно терминирует строки в передаваемом им потоке в соответствии с неким утвержденным протоколом ? А то что автор не знает соглашений этого протокола или они ему попросту фиолетовы, вовсе не говорит о какой бы то ни было "неопределенности", кроме оной в голове автора)
Anatoly Podgoretsky (2009-09-02 14:38:00) [9]> Сергей М. (02.09.2009 14:22:09) [9]
Для реализации потоковых функций, когда конец потока строк неопределен. Если функция текста не умеет работать с символом EOF, то придется придумывать навесной протокол для ее реализации. По умолчанию файловые потоки строк обязаны реагировать на CR, LF, EOF и некоторые другие символы управления потоком, вне зависимости есть ли обратный канал.
Сергей М. (2009-09-02 14:22:00) [10]
> Это нечестная строковая функция
Настолько же нечестная, насколько и TCustomWinSocket.ReceiveText .. )
> придется придумывать механизм реализации EOF
Нафих он тут нужен ?)
Anatoly Podgoretsky (2009-09-02 12:56:00) [11]> Сергей М. (02.09.2009 11:39:07) [7]
Должна, но не обязана :-)
Это нечестная строковая функция, значит придется придумывать механизм реализации EOF.
Сергей М. (2009-09-02 11:39:00) [12]
> функция обязана реагировать и на другие управляющие символы,
> например на #0 и EOF
Не обязана.
Взгляни на реализацию.
Anatoly Podgoretsky (2009-09-02 11:23:00) [13]> Сергей М. (02.09.2009 10:56:05) [5]
Намек есть
function Receiveln(eol: string = CRLF): string;
Более того функция обязана реагировать и на другие управляющие символы, например на #0 и EOF
Сергей М. (2009-09-02 10:56:00) [14]
> 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" ?
cerber (2009-09-02 10:08:00) [15]...или через буфер - CrytoGen (25.08.09 19:38) [1]
cerber (2009-09-02 10:04:00) [16]Receiveln - принимает строковые переменные в формате ASCII.
Если надо передать данные передавай через потоки, предварительно передав(и убедившись в получении приемной стороной) размер потока.
Сергей М. (2009-08-25 21:10:00) [17]
> Символ конца даных не определен
Кемне определен ?
> Пробовал задавать Receiveln(#10)
Почему именно #10, если "не определен" ?
CrytoGen (2009-08-25 19:38:00) [18]используй ReadBuffer