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;
V1版下载地址:http://download.csdn.net/detail/sqldebug_fan/4510076,需要资源10分,有稳定性问题,可以作为研究稳定性用;
V2版下载地址:http://download.csdn.net/detail/sqldebug_fan/5560185,不需要资源分,解决了稳定性问题和提高性能;免责声明:此代码只是为了演示IOCP编程,仅用于学习和研究,切勿用于商业用途。水平有限,错误在所难免,欢迎指正和指导。邮箱地址:[email protected]