Конференция "Сети" » TServerSocket.ReceiveText в Delphi 2009 возвращает '????????...'
 
  • d@vinchi © (09.09.09 19:01) [0]
    В delphi 2009 тип строк по умолчанию юникоидный, но попытки привести полученную строку от TServerSocket.ReceiveText к нормальному виду пока никчекму не привели...
    Кто сталкивался с этой траблой - как решить?
  • Сергей М. © (10.09.09 08:24) [1]
    "Трабла" в том, что передатчик посылает отнюдь не юникод.
    Бессмысленно трактовать юникодом то что им на самом деле не является.
  • d@vinchi © (10.09.09 11:48) [2]
    так как правильно принять?
  • Сергей М. © (10.09.09 12:50) [3]
    ReceiveBuf
  • Anatoly Podgoretsky © (10.09.09 13:13) [4]
    Кстати а как пробовал, где код?
  • d@vinchi © (10.09.09 15:05) [5]
    из всех вариантов наиболее приближенный к ожидаемому результату так:

    var
     sReceiveText: String;
    ...
     sReceiveText:=PAnsiChar(Socket.ReceiveText);
    ...


    хотя предпологаю что так не совсем правильно и вместо пустых строк символ 's', чего явно не должно быть... Иногда при таком варианте в sReceiveText присутствуют куски "мусора". По сути вызов Socket.ReceiveText и так реализован через ReceiveBuf, вот его реализация:

    function TCustomWinSocket.ReceiveText: string;
    begin
     SetLength(Result, ReceiveBuf(Pointer(nil)^, -1));
     SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result)));
    end;


    никак не доганю что не так?
  • Сергей М. © (10.09.09 15:15) [6]

    > чего явно не должно быть


    Начнем с того - а что на самом деле должно быть ?
    Что конкретно ты ожидал увидеть в строке sReceiveText ?
    И какими средствами ты разглядывал содержимое этой строки - под отладчиком или каким-нить ShowMessage() ?
  • d@vinchi © (10.09.09 15:41) [7]
    1. Проект скомпелированный на Delphi 2007 работает как надо, т.е. в sReceiveText получаю строку в нормальном виде ожидаемого формата, на Delphi 2009 эта строка приходет в виде ???????????<вагон всякого мусора>
    2. Конкретно то что мне отправляют если я Вас правильно понял, а отправляют мне строгоотформатированное текстовое сообщение (SIP протокол).
    3. рассматривал под отладчиком...
  • Anatoly Podgoretsky © (10.09.09 15:50) [8]

    > никак не доганю что не так?

    Должно быть function
    TCustomWinSocket.ReceiveText: AnsiString;

  • Сергей М. © (10.09.09 15:50) [9]

    > 3. рассматривал под отладчиком


    Отладчик не показывает "вопросов", если ты им правильно пользуешься.
    Покажи hex-дамп строки..
  • Anatoly Podgoretsky © (10.09.09 15:55) [10]
    Можно написать так

    > function TCustomWinSocket.AnsiReceiveText: AnsiString;
    > begin
    >    SetLength(Result, ReceiveBuf(Pointer(nil)^, -1));
    >    SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result)));
    >
    > end;

    Поскольку кроме ошибки с типом, также еще и SetLenght неверен, итого в функии правильны только две строки, это BEGIN и END
    и таких мест множество, практически в каждой сетевой функции, если используются строки. Эта же проблема и с рядом DB библиотек, точно также безответсвенно подошли и там. Хотя проводили очень долгую компанию по переводу проектов пользователей под Юникод, а сами такого натворили.
  • d@vinchi © (10.09.09 15:59) [11]

    > function TCustomWinSocket.ReceiveText: AnsiString

    так вот у меня
    function TCustomWinSocket.ReceiveText: String


    на сколько я понял это разработчики так спешили перейти на юникод что накосячили в TCustomWinSocket.
  • Anatoly Podgoretsky © (10.09.09 16:07) [12]
    Это я предлагаю написать свою функцию, что бы не трогать генофонд.

    Не знаю связано ли это с спешкой или нет, они просто не тестировали и на Инглише проблема особо не заметна.

    Вместо ReceiveText можно пользоваться ReceiveBuf
  • Сергей М. © (10.09.09 16:09) [13]

    > ReceiveBuf(Pointer(Result)^


    Да, косяк именно в случае, когда Result является WideString.
    Потому и [3]
  • Сергей М. © (10.09.09 16:12) [14]

    > что бы не трогать генофонд


    Думаю, что его можно не трогать, если воспользоваться рантайм-пакетом scktcomp - вряд ли его перекомпиляли. Т.е. внутри него по-прежнему живут анси-строки
  • Anatoly Podgoretsky © (10.09.09 16:15) [15]
    Думаешь, что они и там устроили пакость?
    Это же убийство, если в пакетах Ansi, а в dcu Unicode
    Не думаю, просто они не стали трогать, как было написано string так и оставили, не меняя. А пакеты тоже перекомпилировали.
  • Сергей М. © (10.09.09 16:21) [16]

    > Думаешь, что они и там устроили пакость?


    Все может быть ..

    В принципе ты прав - в ситуации, когда разбираться с этой чехардой нет времени и/или неохота, написать свою функцию будет простейшим и лучшим решением.
  • Anatoly Podgoretsky © (10.09.09 16:48) [17]
    TServerSocket это компонент из Д7 вроде бы?
  • d@vinchi © (10.09.09 16:55) [18]
    Спасибо в очередной раз! переписывать метод не стал т.к. используется в только одном месте, траблу решил так:

    var
    sReceiveText: String;
    ...
     SetLength(sReceiveText, Socket.ReceiveBuf(Pointer(nil)^, -1));
     SetLength(sReceiveText, Socket.ReceiveBuf(Pointer(sReceiveText)^, Length(sReceiveText)));
    ...


    далее работаем со строкой sReceiveText как обычно. Странно что эта ошибка даже в последних обновлениях на BDS 2009 не исправлена...


    > Поскольку кроме ошибки с типом, также еще и SetLenght неверен,
    >  итого в функии правильны только две строки, это BEGIN и
    > END
    > и таких мест множество, практически в каждой сетевой функции,
    >  если используются строки. Эта же проблема и с рядом DB
    > библиотек, точно также безответсвенно подошли и там.

    самое страшное что это еще может много где всплыть...
  • Сергей М. © (10.09.09 17:03) [19]

    > var
    > sReceiveText: String;


    Да почему же опять String, а не AnsiString ?
  • d@vinchi © (10.09.09 17:41) [20]
    т.е. теперь про String вообще нужно забыть?
  • d@vinchi © (10.09.09 17:43) [21]

    > > var
    > > sReceiveText: String;

    это я скопипастил так, там естественно AnsiString...
  • Сергей М. © (11.09.09 08:31) [22]

    > теперь про String вообще нужно забыть?


    В данном контексте String если и можно использовать, то совсем не так - ты в этом убедился, уведев "вопросы".
  • Anatoly Podgoretsky © (11.09.09 11:08) [23]
    > d@vinchi  (10.09.2009 17:41:20)  [20]

    Строки они разные бывают и они разные все поддержаны, включая utf-8
  • evgeny2k © (01.03.10 12:32) [24]
    Я бы вот так написал (работает)

    var
    sReceiveText: AnsiString;
    ...
    SetLength(sReceiveText, Socket.ReceiveLength());
    SetLength(sReceiveText, Socket.ReceiveBuf(Pointer(sReceiveText)^, Length(sReceiveText)));

    Или под Билдером
    AnsiString _Str;

    _Str.SetLength(Socket->ReceiveLength());
    Socket->ReceiveBuf(_Str.c_str(), _Str.Length());
    RichEdit1->Lines->Add(_Str);
    Эх, не спроста они эти компоненты на палитру по-умолчанию не вывели...
 
Конференция "Сети" » TServerSocket.ReceiveText в Delphi 2009 возвращает '????????...'
Есть новые Нет новых   [134437   +30][b:0][p:0.001]