• 0
rareMax

Как Получить текст по TCP (Indy) в нужной кодировке?

Вопросы

Добрый день! Возник еще один вопрос по работе с FM3. Нашел на диске заброшенный проект(клиент для чата). Захотелось переписать его под Android. Только проблема заключается вот в чем. При получении текста я раньше писал так:

fInput:= fClient.Socket.ReadLn(TEncoding.UTF8);

Но сейчас видимо что-то изменилось в ИнДи(из-за кроссплатформености полагаю?), и TEncoding.UTF8 нельзя использовать. А без него в неправильной кодировке приходит текст. Кто может, приведите пример, как получить текст с сервера с преобразованием кодировки?

 

P.S. Ярослав, если я не в том разделе создал тему, просьба переместить ее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 ответа на этот вопрос

  • 0

Добрый день,

 

Теперь он в качестве параметра принимает объект другого класса, а именно интерфейса IIdTextEncoding, который описывает основные методы по работе с потоком.

 

Естественно, что этот интерфейс вам не нужно реализовывать, а нужно найти его реализацию для UTF8 кодировки. 

 

Собственно смотрим в IdGlobal.pas и видим там глобальные процедуры по получению нужных реализаций в требуемых кодировках:

  IdTextEncodingType = (encIndyDefault, encOSDefault, enc8Bit, encASCII, encUTF16BE, encUTF16LE, encUTF7, encUTF8);

  function IndyTextEncoding(AType: IdTextEncodingType): IIdTextEncoding; overload;
  function IndyTextEncoding(ACodepage: Word): IIdTextEncoding; overload;
  function IndyTextEncoding(const ACharSet: String): IIdTextEncoding; overload;
  {$IFDEF DOTNET}
  function IndyTextEncoding(AEncoding: System.Text.Encoding): IIdTextEncoding; overload;
  {$ENDIF}
  {$IFDEF HAS_TEncoding}
  function IndyTextEncoding(AEncoding: TEncoding): IIdTextEncoding; overload;
  {$ENDIF}

  function IndyTextEncoding_Default: IIdTextEncoding;
  function IndyTextEncoding_OSDefault: IIdTextEncoding;
  function IndyTextEncoding_8Bit: IIdTextEncoding;
  function IndyTextEncoding_ASCII: IIdTextEncoding;
  function IndyTextEncoding_UTF16BE: IIdTextEncoding;
  function IndyTextEncoding_UTF16LE: IIdTextEncoding;
  function IndyTextEncoding_UTF7: IIdTextEncoding;
  function IndyTextEncoding_UTF8: IIdTextEncoding;

Тут либо используем конкретный метод  IndyTextEncoding_UTF8, либо же используем вариант через:

IndyTextEncoding(IdTextEncodingType.encUTF8)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

ааа, они глобальные, а я интерфейс  IIdTextEncoding смотрел, там ничего похожего не было. Спасибо, сейчас попробую :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Гость
Эта тема закрыта для публикации ответов.

  • Похожий контент

    • От bossalex
      Недавно компилил приложение на Delphi  FMX Android  при обращении  к серверу https при выполнении Get запроса от компонента TIdHttp запросил библиотеку "Could not load SSL library" используется протокол sslvTLSv1_2 в windows все пашет в андроид нет , накопал что можно подключить библиотеки  libssl.so и  libcrypto.so через  deployment .assets\internal , А вот как в коде дальше их использовать никто примерчик не выложил, хоть и обсуждали на интернет просторах 100 раз, те как прикрутить  к IdSSLIOHandlerSocketOpenSSL1.SSLOptions.CertFile. Если есть у кого код выложите пожалуйста? или скинте по email bossalex@ya.ru
      IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method.sslvTLSv1_2;
      IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Mode.sslmUnassigned;
       
    • От Рагим
      Добрый день. Решил сегодня сделать некоторые доработки в приложение написанное на XE7 под Андроид и столкнулся со следующей проблемой: приложение не получает информацию через связку TIdTCPClient/TIdTCPServer. До этого все работало.
      Отправляю сообщение с компьютера через TIdTCPClient:
      try     form2.IdTCPClient1.Connect;     form2.IdTCPClient1.IOHandler.WriteLn(ss,enUTF8);     form2.IdTCPClient1.Disconnect;    except      showmessage('Error');      end;     end;//try получаю (вернее не получаю) на телефоне под Андроид:
      procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); begin  l := AContext.Connection.IOHandler.ReadLn(enUTF8);  showmessage(l); end;  
      В чем может быть проблема и как решить?
    • От Рагим
      Доброго времени суток.
      Есть приложение на Windows (сервер) и есть от 1 до 4 приложений (клиенты) на Андроид. Все устройства в сети. IP адреса клиентов не известны серверу, а адрес сервера клиентам. Приложения после того как узнают адреса друг друга, будут обмениваться сообщениями через TIdTcpClient и TIdTcpServer. 
      Как лучше реализовать распознавание клиентов в сети? Делаю сейчас используя Tethering, но способ мне не нравится.
    • От Камышев Александр
      tcp_client->Socket->Write( data_out, false ); data_out - TMemoryStream размером около 1,5 Мб, если использовать wifi все ок, в OnWork исправно AWorkCount по 96 байт шлет.
      Выключаю wifi проверяю интернет соединение - все ок, небольшие массивы по несколько килобайт уходят без проблем.
      Впихиваю 1,5 метра - AWorkCount показывает какие-то либо терабайты либо отрицательные значения.
      Ошибки нет, тупо висит. Что ему не так то? help
    • От Morfi
      Здравствуйте!
      Пытаюсь реализовать алгоритм PBKDF2-SHA1. Для вычисления HMAC-SHA1 использую класс TidHMACSHA1.
      Код PBKDF2-SHA1 нашел на просторах интернета и немного подкорректировал для использования с INDY (TidHMACSHA1):
      function PBKDF2Sha1(pass, salt: string; count, kLen: Integer): string; function IntX(i: Integer): string; inline; begin Result := Char(i shr 24) + Char(i shr 16) + Char(i shr 8) + Char(i); end; var D, I, J: Integer; T, F, U, wPass: TIdBytes; begin wPass := ToBytes(pass); D := Ceil(kLen / (160 div 8)); for i := 1 to D do begin F := EncryptHMACSha1(ToBytes(salt + IntX(i)), wPass); U := F; for j := 2 to count do begin U := EncryptHMACSha1(U, wPass); //<-- Проблема F := XorBlock(F, U); end; T := T + F; end; Result := ToHex(Copy(T, 1, kLen)); end; Для вычисления HMAC-SHA1 используется функция EncryptHMACSha1:
      function EncryptHMACSha1(Input, AKey: TIdBytes): TIdBytes; var HMachSha1: TIdHMACSHA1; begin HMachSha1 := TIdHMACSHA1.Create; try HMachSha1.Key := AKey; Result := HMachSha1.HashValue(Input); finally HMachSha1.Free; end; end; Возникает проблема, когда эта функция используется 6-й раз в функции PBKDF2Sha1:
      for i := 1 to D do // D := 2 begin F := EncryptHMACSha1(ToBytes(salt + IntX(i)), wPass); // Использование функции (разы): 1-й, 4-й U := F; for j := 2 to count do // count := 3 begin U := EncryptHMACSha1(U, wPass); // <--Проблема! Использование функции (разы): 2-й, 3-й, 5-й, !6-й! F := XorBlock(F, U); end; T := T + F; end; Возникает исключение в глубинах INDY-кода:

      а точнее в функции TIdHashSHA1.NativeGetHashBytes (файл: idHashSHA,pas) на строке с кодом:
      SetLength(Result, SizeOf(UInt32)*5); // в файле строка под номером 460 Помогите решить данную проблему.
       
      Версии:
      Delphi: 10.1
      INDY: 10.6.2.5341
    • От Rusland
      Пытаюсь скачать XML с курсами валют с cbr.ru. Получаю ошибку Project raised exception class EEncodingError with message 'No mapping for the Unicode character exists in the target multi-byte code page'. Как исправить?
      //aUrl = http://www.cbr.ru/scripts/XML_daily.asp function GetXML(aURL: string): String; var Http: THTTPClient; Ss: TStringStream; begin Result:=''; Http:=THTTPClient.Create; try Ss:=TStringStream.Create('', TEncoding.UTF8); Http.Get(aURL,ss); Result:=Ss.DataString; // тут ошибка except end; Http.Free; end;
    • От serg557
      Вопрос заключается в следующем - есть сервер сделанный в VCL
      Server1->DefaultPort=6590 void __fastcall TForm3::Server1Execute(TIdContext *AContext) // на запрос от клиента { TIdIOHandler *a = AContext->Connection->IOHandler; UnicodeString res = a->ReadLn(IndyUTF8Encoding(true)); if (res == "zapros") { if (ListBox1->Items->Strings[0]!="") { a->WriteLn(ListBox1->Items->Strings[0],IndyUTF8Encoding(true)); a->WriteLn(ListBox3->Items->Strings[0],IndyUTF8Encoding(true)); ListBox2->Items->Add("("+AContext->Connection->Socket->Binding->IP+")"+ListBox1->Items->Strings[0]); } есть клиент написанный на vcl
      //порт указан вручную Client1->Host =Edit2->Text; if (Client1->Connected()==false) { try { Client1->Connect(); } catch(...) { ShowMessage("Не удалось подключиться"); } } TIdIOHandler *a = Client1->IOHandler; a->WriteLn("zapros",enUTF8); Edit1->Text=a->ReadLn(enUTF8); Edit5->Text=a->ReadLn(enUTF8); a->Free(); } рабочий, захотел переложить его на FMX:
      Client1->Port=6590; Client1->Host=Edit1->Text; if (Client1->Connected()==false) { try { Client1->Connect(); } catch(...) { Client1->Socket->Close(); ShowMessage("Не удалось подключиться"); } } TIdIOHandler *a = Client1->IOHandler; a->WriteLn("zapros",IndyUTF8Encoding(true)); Edit3->Text=a->ReadLn(IndyUTF8Encoding(true)); Edit5->Text=a->ReadLn(IndyUTF8Encoding(true)); Client1->Socket->Close(); a->Free(); } выдает ошибку 
       Может подскажет кто-как их помирить? (Сервер переписывать не вариант  )
    • От loony-pants
      Впервые взялся за разработку Клиент-серверного приложения.  Нашёл пример с IdTCPServer и IdTCPClient, попытался начать с реализации  запроса-ответа. При нажатии на кнопку клиент зависает (Как я понял - соединение не происходит). Ip адрес указывал просмотрев с сайта 2ip.ru и тот, что в "сведениях о сетевом подключении" - результат один и тот же - Зависает клиент. Пробовал с IdUDPClient и IdUDPServer - работает, НО только во внутренней сети, а мне необходим глобальный обмен.
       
      Клиент:
      procedure TForm2.LoginButtonClick(Sender: TObject); begin try IdTCPClient1.Host :='127.0.0.1'; /// Менял IP адрес   IdTCPClient1.Port:=55560; IdTCPClient1.Connect; except Memo2.Lines.Add('Не удается соединиться с указанным сервером'); Exit; end; Memo2.Lines.Append(IdTCPClient1.Socket.ReadLn); IdTCPClient1.Disconnect; end; Сервер:
      procedure TForm1.FormCreate(Sender: TObject); begin section1 := TCriticalSection.Create; idTcpServer1.DefaultPort:=55560; idTcpServer1.Active:=true; end; procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); var strText: String; begin strText := AContext.Connection.Socket.ReadLn; AContext.Connection.Socket.WriteLn('Login: ' + strText); section1.Enter; Edit3.Text := AContext.Connection.Socket.Binding.PeerIP; section1.Leave; Memo1.Lines.Add(AContext.Connection.Socket.Binding.PeerIP); AContext.Connection.Disconnect; end;
    • От M1shQa
      Добрый день госопда. Есть одно приложение на плюсах под андроид, получаю данные через сокеты по tcp посредством компоненты от Indy (только tcp сокеты, других вариантов начальство не дает). Проблема состоит в том, что каждый раз, когда идет получение на пример картинки, то вcё зависает и висит во фризе до конца получения данных, весь телефон висит! Можно как то решить эту проблему? Особенно это ужасает когда приложение работает в фоне и пытается выкачать картинку, телефон просто зависает и все, ничего не поделаешь..
    • От MIB
      Столкнулся с засадой: нужно передать с клиента (андроид) на сервер (Win) данные
      TArray_Data = record fText_a: String;   a,b:double; ... end; Ранее всегда использовал стандартные ServerSocket / ClientSocket и соответственно ReceiveBuf / SendBuf, а вот в Инди такое не проходит.
      Подскажите, плз, вариант решения? 
       
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу