Как отправить текст в UTF-8 с помощью Indy TIdTCPServer в C ++ Builder - PullRequest
1 голос
/ 18 марта 2011

Мое клиентское приложение j2me читает поток ввода текста с использованием UTF-8

reader = new InputStreamReader(in,"UTF-8");

, и мой сервер при подключении отправляет текст с помощью этого оператора

AContext->Connection->IOHandler->WriteLn(cxMemo1->Text,TEncoding::UTF8);

, но в результате появляется текст, показывающий странные символылайк ???????????????????????????????????????

Где я делаю неправильно?

также когда я пытался загрузить файл данных кодировки utf-8 таким способом

AContext->Connection->IOHandler->WriteFile("c:\\fids.xml");

это все то же самое!

Ответы [ 2 ]

0 голосов
/ 19 марта 2011

'?' символы появляются, когда данные проходят преобразование Unicode-to-Ansi в кодировку Ansi, которая не поддерживает преобразование символов Unicode.

Какую версию C ++ Builder вы используете? В версиях, предшествующих CB2009, вы должны указать Indy кодирование данных AnsiString, которые вы передаете. Indy по умолчанию имеет значение ASCII (то есть: TIdTextEncoding::ASCII) для большинства операций на основе строк. Это может быть переопределено при необходимости с помощью необязательных параметров AAnsiEncoding, свойства TIdIOHandler::DefAnsiEncoding или глобальной настройки Idglobal::GIdDefaultAnsiEncoding. Если вы не укажете правильную кодировку, данные AnsiString могут быть неправильно преобразованы в Unicode, а затем преобразованы в UTF-8. Например:

AContext->Connection->IOHandler->WriteLn(cxMemo1->Text, TIdTextEncoding_UTF8, TTIdTextEncoding_Default);

Или:

AContext->Connection->IOHandler->DefAnsiEncoding = TIdTextEncoding_Default;
AContext->Connection->IOHandler->WriteLn(cxMemo1->Text, TIdTextEncoding_UTF8);

При желании вы также можете использовать свойство TIdIOHandler::DefStringEncoding, если не хотите указывать кодировку UTF-8 для каждого вызова:

AContext->Connection->IOHandler->DefStringEncoding = TIdTextEncoding_UTF8;
AContext->Connection->IOHandler->WriteLn(cxMemo1->Text);

Теперь, с учетом сказанного, тот факт, что WriteFile() также отправляет данные, которые J2ME обрабатывает неправильно, говорит мне, что Indy не является корнем проблемы. WriteFile () просто копирует необработанные данные файла как есть, без какой-либо интерпретации. Если вы отправите файл в кодировке UTF-8, то октеты в кодировке UTF-8 будут отправлены в J2ME.

Я предлагаю вам использовать анализатор пакетов, такой как Wireshark, для проверки данных, которые посылает Indy. Это точно скажет вам, действительно ли Indy виноват или нет.

* PS: обратите внимание, что в приведенных выше примерах я использую макросы Indy TIdTextEncoding вместо TEncoding напрямую. Это связано с тем, что логика TIdTextEncoding в Indy работает с некоторыми ошибками в классах Embarcadero TEncoding. Кроме того, мы собираемся постепенно прекратить прямую поддержку TEncoding в Indy 11 и расширить на TIdTextEncoding, чтобы у Indy было больше контроля, чем у Embarcadero.

0 голосов
/ 18 марта 2011

Indy 10 полностью поддерживает кодировку UTF-8. Я сам работал с его компонентом TIdFTP и успешно загрузил текстовые файлы Unicode. Из того, что я могу из этого сделать:

  1. Ваш тип соединения / передачи установлен на ftASCII вместо ftBinary.
  2. Ваш апплет J2ME / Платформа хоста не поддерживает UTF-8
...