Конференция "Сети" » Подвисание при вызове TcpClient1.Receiveln() [WinXP]
 
  • alik (25.08.09 19:33) [0]
    Добрый вечер,

    С помощью компоненты TcpClient необходимо прочитать данные переменной длины. Символ конца даных не определен и не используется и при использовании метода Receiveln,
    как показано ниже, программа подвисает.

    var
    s: String;
    begin
    s := TcpClient1.Receiveln
    ...
    end;

    Пробовал задавать Receiveln(#10), но тогда читается какой-то кусок пришедших данных и все.

    Прошу посоветуйте, как разрешить или обойти данную заковырькю!
  • CrytoGen (25.08.09 19:38) [1]
    используй ReadBuffer
  • Сергей М. © (25.08.09 21:10) [2]

    > Символ конца даных не определен


    Кем не определен ?


    > Пробовал задавать Receiveln(#10)


    Почему именно #10, если "не определен" ?
  • cerber (02.09.09 10:04) [3]
    Receiveln - принимает строковые переменные в формате ASCII.
    Если надо передать данные передавай через потоки, предварительно передав(и убедившись в получении приемной стороной) размер потока.
  • cerber (02.09.09 10:08) [4]
    ...или через буфер - CrytoGen   (25.08.09 19:38) [1]
  • Сергей М. © (02.09.09 10:56) [5]

    > 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" ?
  • Anatoly Podgoretsky © (02.09.09 11:23) [6]
    > Сергей М.  (02.09.2009 10:56:05)  [5]

    Намек есть

    function Receiveln(eol: string = CRLF): string;

    Более того функция обязана реагировать и на другие управляющие символы, например на #0 и EOF
  • Сергей М. © (02.09.09 11:39) [7]

    > функция обязана реагировать и на другие управляющие символы,
    >  например на #0 и EOF


    Не обязана.
    Взгляни на реализацию.
  • Anatoly Podgoretsky © (02.09.09 12:56) [8]
    > Сергей М.  (02.09.2009 11:39:07)  [7]

    Должна, но не обязана :-)
    Это нечестная строковая функция, значит придется придумывать механизм реализации EOF.
  • Сергей М. © (02.09.09 14:22) [9]

    > Это нечестная строковая функция


    Настолько же нечестная, насколько и TCustomWinSocket.ReceiveText .. )


    > придется придумывать механизм реализации EOF


    Нафих он тут нужен ?)
  • Anatoly Podgoretsky © (02.09.09 14:38) [10]
    > Сергей М.  (02.09.2009 14:22:09)  [9]

    Для реализации потоковых функций, когда конец потока строк неопределен. Если функция текста не умеет работать с символом EOF, то придется придумывать навесной протокол для ее реализации. По умолчанию файловые потоки строк обязаны реагировать на CR, LF, EOF и некоторые другие символы управления потоком, вне зависимости есть ли обратный канал.
  • Сергей М. © (02.09.09 14:49) [11]

    > Anatoly Podgoretsky ©   (02.09.09 14:38) [10]


    > когда конец потока строк неопределен


    Он не может быть неопределен, иначе это не протокол, а фуфло)
    На чем я и заострил внимание автора.
    EOF - значит EOF, NULL - значит NULL, прочий символ или комбинация символов - значит они самые, НО нельзя при этом говорить что "символ конца данных не определен".
    Как же он, спрашивается, неопределен, если передатчик исправно терминирует строки в передаваемом им потоке в соответствии с неким утвержденным протоколом ? А то что автор не знает соглашений этого протокола или они ему попросту фиолетовы, вовсе не говорит о какой бы то ни было "неопределенности", кроме оной в голове автора)
  • Anatoly Podgoretsky © (02.09.09 15:13) [12]
    > Сергей М.  (02.09.2009 14:49:11)  [11]

    Ты рассказываешь про побочные эффекты данного компонента и не готов абстрагироваться от них.
  • Сергей М. © (02.09.09 15:56) [13]

    > 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 © (02.09.09 16:03) [14]
    > Сергей М.  (02.09.2009 15:56:13)  [13]

    Если бы не называли ReceiveLN то и претензий бы не было.
  • Сергей М. © (02.09.09 16:33) [15]

    > Anatoly Podgoretsky ©   (02.09.09 16:03) [14]


    У меня-то претензии не к компоненту и не к тому как в нем обозвали метод, а к формулировке вопроса:

    > Символ конца даных не определен и не используется и при
    > использовании метода Receiveln,
    > как показано ниже, программа подвисает


    1. Если ReceiveLn вызван без параметров, то это не означает что символ не определен и не используется - он попросту явно не указан, что подразумевает осознанное CRLF, т.е. от партнера мы ожидаем в качестве разделителя именно CRLF и ничто иное.

    2. Последующие пляски с бубном


    > Пробовал задавать Receiveln(#10)


    говорят о том, что автор ни сном ни духом не ведает про соглашения о термирнировании строк, используемые партнером по соединению.
    А именно с изучения оных и следовало начать, прежде чем начинать заниматься научным тыком)

    3. Receiveln не может подвешивать вызывающий поток, если не используется режим bmBlocking, а о режиме автор, кстати, упомянуть не удосужился.

    4. В режиме bmNonBlocking при получении результатом вызова ReceiveLn пустой строки потребуются дополнительные телодвижения для определения причин такого результата - то ли партнер действительно послал пустую строку с ожидаемым терминатором, то ли он чего-от там послал, но еще не все пришло,  то ли он вообще еще нишиша не посылал, то ли соединение корректно закрыто партнером
  • Anatoly Podgoretsky © (03.09.09 09:12) [16]
    > Сергей М.  (02.09.2009 16:33:15)  [15]

    Если по формулировке, то если "Символ конца даных не определен", то метод будет висеть до скончания века или разрыва соединения.
  • Сергей М. © (03.09.09 09:29) [17]
    Подождем автора)
  • Anatoly Podgoretsky © (03.09.09 09:58) [18]
    > Сергей М.  (03.09.2009 09:29:17)  [17]

    C ним проблемы.
 
Конференция "Сети" » Подвисание при вызове TcpClient1.Receiveln() [WinXP]
Есть новые Нет новых   [134437   +29][b:0][p:0.001]