使用 TIdCmdTCPClient 发送 unicode 命令

Sending unicode command with TIdCmdTCPClient

我正在使用 Delphi XE6 和 Indy 10

我想将 Unicode 字符串作为命令从 TIdCMDTCPClient 发送到 TIdCMDTCPServer

我正在使用 IdCMDTCPClient 组件的 SendCMD 方法发送命令,但收到的命令显示为 ' ? ' 字符 !

事实上我有一个命令(例如:"USER_REG")和一些参数,参数是一个 Unicode 字符串(波斯字符)

我已将命令编码设置为 IndyTextEncoding_UTF8 或使用 UTF8Encode 函数对命令进行编码,但没有机会!

命令示例:

CMD := 'USER_REG#register_user(' + QuotedStr('محمود مهری') + ')';
TCPClient.SendCmd(CMD, -1, IndyTextEncoding_UTF8);

TCPClient.SendCmd(UTF8Encode(CMD), -1, IndyTextEncoding_UTF8);

如何将 Unicode 字符串作为命令发送?

谢谢...

TIdCmdTCPServerTIdCmdTCPClient 不能一起使用。如果您使用 TIdCmdTCPServer,则应改用 TIdTCPClient。如果你想使用TIdCmdTCPClient,那么至少不要使用它的SendCmd()GetResponse()方法。 TIdCmdTCPClient 使用内部读取线程从服务器接收消息。该线程将干扰 GetResponse() 的阅读(SendCmd() 在内部调用 GetResponse())。改为使用客户端的 IOHandler.WriteLn() 方法,然后让 TIdCmdTCPClient.CommandHandlers 读取服务器的响应。

也就是说,在实际发送时指定 IndyTextEncoding_UTF8 是正确的做法。您也可以改为设置客户端的 IOHandler.DefStringEncoding 属性。无论哪种方式,在这种情况下使用 UTF8Encode() 在 Delphi 2009+ 中都是无用的,因为 SendCmd()(和 WriteLn())将 UnicodeString 作为输入,因此 UTF -8 编码的 RawByteString UTF8Encode() returns 将被 RTL 转换回 UTF-16 UnicodeString,然后 IndyTextEncoding_UTF8 将重新编码回传输期间再次使用 UTF-8。那是无用的开销。

在服务器端,您需要在读取时使用 IndyTextEncoding_UTF8,以便正确解码传入的 UTF-8 编码命令。由于 TIdCmdTCPServer 正在为您进行实际阅读,因此您必须将 IndyTextEncoding_UTF8 分配给 OnConnect 事件中的 AContext.Connection.IOHandler.DefStringEncoding 属性。否则,将使用 Indy 的默认编码,默认情况下该编码为 US-ASCII(可通过 IdGlobal.GIdDefaultTextEncoding 变量配置)。这就是您看到客户端的非 ASCII 字符被转换为 ? 字符的原因。 US-ASCII 不支持 #127.

以上的字符