UTF-8
UTF-8是UNICODE的一种变长字符编码又称万国码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码UNICODE字符。用在网页上可以同一页面显示中文简体繁体及其它语言(如日文,韩文)。
使用UTF-8的好处是现在一些手机平台都是使用UTF-8,另外在一些嵌入式平台,如果不支持中文,只支持英文,可以不转换,UTF-8就可以识别。
DELPHI默认支持的编码是ANSI,为了支持UTF-8,需要转换下,为了编程简便性,我们只在发包和解包的地方进行UTF-8转换。
发包:
function TBaseClientSocket.ControlCommand(const ACommand: string;
ARequest, AResponse: TStrings; const AData: string): Boolean;
var
slBuff: TStringList;
dwPacketLen, dwCommandLen, dwCode: Cardinal;
sBuff: string;
utf8Command, utf8Data: UTF8String;
begin
try
slBuff := TStringList.Create;
try
FClient.ReadTimeout := FTimeOutMS;
FClient.MaxLineLength := 1024 * 1024 * 1024;
slBuff.Add('[' + CSRequest + ']');
slBuff.Add(CSCommand + CSEqualSign + ACommand);
if Assigned(ARequest) then
slBuff.AddStrings(ARequest);
sBuff := slBuff.Text;
utf8Command := AnsiToUtf8(sBuff); //把ANSI转为UTF-8
if not IsEmptyStr(AData) then
utf8Data := AnsiToUtf8(AData); //把ANSI转为UTF-8
dwPacketLen := SizeOf(Cardinal) + Length(utf8Command) + Length(utf8Data); //总长度
dwCommandLen := Length(utf8Command); //命令长度
FClient.WriteCardinal(dwPacketLen, False); //发送整个包长度
FClient.WriteCardinal(dwCommandLen, False); //发送命令长度
FClient.WriteBuffer(PUTF8String(utf8Command)^, dwCommandLen, True); //发送命令内容
if not IsEmptyStr(AData) then
FClient.WriteBuffer(PUTF8String(utf8Data)^, Length(utf8Data), True); //发送数据
dwPacketLen := FClient.ReadCardinal(False); //读取整个包的长度
dwCommandLen := FClient.ReadCardinal(False); //读取命令长度
SetLength(utf8Command, dwPacketLen - SizeOf(Integer));
FClient.ReadBuffer(PUTF8String(utf8Command)^, dwPacketLen - SizeOf(Integer)); //读取后续内容
slBuff.Clear;
slBuff.Text := Utf8ToAnsi(utf8Command); //转换为ANSI
dwCode := Cardinal(StrToInt(slBuff.Values[CSCode]));
Result := dwCode = 0;
if not Result then
FLastError := GetErrorCodeString(dwCode) + ': ' + slBuff.Values[CSMessage];
if Assigned(AResponse) then
AResponse.Text := slBuff.Text;
finally
slBuff.Free;
end;
except
on E: Exception do
begin
FLastError := E.Message;
Result := False;
end;
end;
end;解包:
function TBaseSocket.DecodePacket(APacketData: PByte;
const ALen: Integer): Boolean;
var
CommandLen: Integer;
UTF8Command: UTF8String;
begin
if ALen > 4 then //命令长度为4字节,因而长度必须大于4
begin
CopyMemory(@CommandLen, APacketData, SizeOf(Cardinal)); //获取命令长度
Inc(APacketData, SizeOf(Cardinal));
SetLength(UTF8Command, CommandLen);
CopyMemory(PUTF8String(UTF8Command), APacketData, CommandLen); //读取命令
Inc(APacketData, CommandLen);
FRequestData := APacketData; //数据
FRequestDataLen := ALen - SizeOf(Cardinal) - CommandLen; //数据长度
FRequest.Text := Utf8ToAnsi(UTF8Command); //把UTF8转为Ansi
Result := True;
end
else
Result := False;
end;这样好处就是外部编程接口就都是ANSI,和DELPHI保持一致,应用编写就可以不用注意这个细节。
V1版下载地址:http://download.youkuaiyun.com/detail/sqldebug_fan/4510076,需要资源10分,有稳定性问题,可以作为研究稳定性用;
V2版下载地址:http://download.youkuaiyun.com/detail/sqldebug_fan/5560185,不需要资源分,解决了稳定性问题和提高性能;免责声明:此代码只是为了演示IOCP编程,仅用于学习和研究,切勿用于商业用途。水平有限,错误在所难免,欢迎指正和指导。邮箱地址:fansheng_hx@163.com
1207



被折叠的 条评论
为什么被折叠?



