Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Кодировка Indy10


Автор: dvamaster 27.12.2010, 10:14
Доброго времени суток!!! Indy 10 билд 4537

при отправке через сокет строки с русскими буквами они конвертируются в вопросы.

Код

    AContext.Connection.Socket.Write(msg); // где msg строка


корявое преобразование происходит в функции ToBytes, обратите внимание на AByteEncoding и ASrcEncoding

Код

procedure TIdIOHandler.Write(const AOut: string; AByteEncoding: TIdTextEncoding = nil
  {$IFDEF STRING_IS_ANSI}; ASrcEncoding: TIdTextEncoding = nil{$ENDIF}
  );
begin
  if AOut <> '' then begin
    AByteEncoding := iif(AByteEncoding, FDefStringEncoding);
    {$IFDEF STRING_IS_ANSI}
    ASrcEncoding := iif(ASrcEncoding, FDefAnsiEncoding, encOSDefault);
    {$ENDIF}
    Write(
      ToBytes(AOut, -1, 1, AByteEncoding
        {$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}
        )
      );
  end;
end;


далее в глубину вложения функций упираемся в

Код

function TIdASCIIEncoding.GetBytes(AChars: PIdWideChar; ACharCount: Integer;
  ABytes: PByte; AByteCount: Integer): Integer;
var
  i : Integer;
begin
  Result := IndyMin(ACharCount, AByteCount);
  for i := 1 to Result do begin
    // replace illegal characters > $7F
    if Word(AChars^) > $007F then begin
      ABytes^ := Byte(Ord('?'));
    end else begin
      ABytes^ := Byte(AChars^);
    end;
    //advance to next char
    Inc(AChars);
    Inc(ABytes);
  end;
end;


а вот и пресловутый кусочек

Код

if Word(AChars^) > $007F then begin
      ABytes^ := Byte(Ord('?'));
    end else begin
      ABytes^ := Byte(AChars^);


выходит все в этих классах.

Вывод, как от этого преобразования избавиться?

Автор: Akella 27.12.2010, 15:31
передавать в юникоде?

Автор: salik 28.1.2011, 18:21
Чтобы небыло кракозябры надо делать так:

посылаем:
Код

procedure TForm1.Button3Click(Sender: TObject);
begin
  Client.IOHandler.WriteLn(Edit1.Text, TEncoding.UTF8);
end;


Принимаем:
Код

procedure TForm1.SrvExecute(AContext: TIdContext);
begin
  REMessList.Lines.Add(AContext.Connection.IOHandler.ReadLn(TEncoding.UTF8));
end



Автор: salik 1.2.2011, 23:45
Задача в том, чтобы принять русский текст в параметрах. Проблема в том что текст отображается "плохо".

после подключение поумалчанию ставлю кодовую страницу UTF8
Код

procedure TForm1.AClientOnExecute(Sender: TObject);// событие ActionList
begin
  try
     Client.Connect;
     Client.Socket.DefStringEncoding := enUTF8;    
  except on E: EIdException do
     REMessList.Lines.Add('Ошибка при подключении клиента: ' + E.Message);
  end;
end;


подскажите что я делаю не так
Код

procedure TForm1.SrvCommandHandlers0Command(ASender: TIdCommand);
begin
  if ASender.Params.Count = 2 then begin
    CS := TCriticalSection.Create;
    try
     CS.Enter;
     ASender.Context.Connection.Socket.DefStringEncoding := enUTF8;      
     REMessList.Lines.Add('выполнено('+ASender.Params[0]+')' + #13 + 'выполнено('+ASender.Params[1]+')');
     ASender.Reply.Text.Text := 'test vipolnen';
    finally
     CS.Leave;
     CS.Free;
    end;
    ASender.Reply.Text.Text := 'test vipolnen';
  end;
end;


PS: иероглифы выходят только при выполнении команды первый раз . Потом проблем нет. (TiDCMDTCPServer TIDCMDTCPClient)

Автор: dvamaster 27.2.2011, 17:27
salik, спасибо  smile

Добавлено через 2 минуты и 11 секунд
Цитата(salik @  2.2.2011,  02:45 Найти цитируемый пост)
иероглифы выходят только при выполнении команды первый раз

Попробуй в OnConnect сделать, один раз

Автор: salik 8.3.2011, 23:44
Как альтернативу к enUTF8 можно использовать конструкцию 
Код

TIdTextEncoding.GetEncoding(866);


Входной параметр функции - это кодовая страница. 
Это работает (обычный windows клиент telnet отображает корректно русский текст).

Вы можете указать свое значение, например 1251.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)