1. 개요
Delphi2009 이후부터 기본 문자열이 유니코드를 지원하게 됨에 따라 인디 컴포넌트를 통해 전송되는 UTF8 문자열이 안전하게 전송되지 못하는 문제가 있다. UTF8 문자열을 소켓을 통해 안전하게 전송하는 방법을 찾아 보자
2. 기존처리 방식
//전송부
_Client := TIdTCPClient.Create(nil);
_Client.Host := Host;
_Client.Port := Port;
try
_Client.Connect;
_Client.IOHandler.WriteLn('Hello World!');
_Client.IOHandler.WriteLn('안녕하세요!');
finally
_Client.free;
end;
// 수신부(TIdTCPServer)
procedure TfrmDebugMain.IdTCPServer1Execute(AContext: TIdContext);
var
msg1, msg2 : string;
begin
try
msg1 := AContext.Connection.IOHandler.ReadLn;
msg2 := AContext.Connection.IOHandler.ReadLn;
Memo1.Lines.Add(msg1);
Memo1.Lines.Add(msg2);
finally
end;
end;
위와 같은 기존 방식으로 처리했을 경우 영문은 정상적으로 나오나 한글 등 UTF8 문자열은 다음과 같이 나타난다.
Hello World!
???? ????!
3. 안전한 UTF8 문자열 전송 방법
전송시 UTF8 문자열을 Base64로 엔코딩후 전송 및 수신후 다시 디코딩 하는 방식을 사용을 추천함
//Base64 Encode/Decode 함수
uses
EncdDecd;
...
function Encode(const Input: string): AnsiString;
var
utf8: UTF8String;
begin
utf8 := UTF8String(Input);
Result := EncdDecd.EncodeBase64(PAnsiChar(utf8), Length(utf8));
end;
function Decode(const Input: AnsiString): string;
var
bytes: TBytes;
utf8: UTF8String;
begin
bytes := EncdDecd.DecodeBase64(Input);
SetLength(utf8, Length(bytes));
Move(Pointer(bytes)^, Pointer(utf8)^, Length(bytes));
Result := string(utf8);
end;
..
// 전송부
if _Client.Connected then
begin
_Client.IOHandler.WriteLn(Encode('Hello World!'));
_Client.IOHandler.WriteLn(Encode('안녕하세요!'));
end;
// 수신부
procedure TfrmDebugMain.IdTCPServer1Execute(AContext: TIdContext);
var
msg1, msg2 : string;
begin
try
msg1 := Decode(AContext.Connection.IOHandler.ReadLn);
msg2 := Decode(AContext.Connection.IOHandler.ReadLn);
Memo1.Lines.Add(msg1);
Memo1.Lines.Add(msg2);
finally
end;
end;
처리결과
Hello World!
안녕하세요!
반응형
'IT > 델파이' 카테고리의 다른 글
안드로이드 앱개발 키 저장소 만들기(Provisioning) (0) | 2023.02.12 |
---|---|
안드로이드 앱 배포 (0) | 2023.02.12 |
날짜 연산 정리 (DateUtils.pas) (0) | 2023.02.09 |
Enum 변수 설정 (0) | 2023.02.08 |
TListView에서 마우스가 클릭한 위치의 Item과 Cell Column을 인지하는 방법 (0) | 2023.02.08 |