【问题标题】:Working with Socket Recv Method in Delphi XE5在 Delphi XE5 中使用 Socket Recv 方法
【发布时间】:2013-10-21 06:41:08
【问题描述】:

我最近将我的 Delphi 7 IDE 更改为 Delphi XE5(大变化)。我正在开发一个小型客户端/服务器应用程序,但在尝试读取字符串时遇到问题。

我的代码:

Function TIOHandler.readString(Var data: String): Integer;
Var
  byteReceived: Integer;
  buff: Array Of Char;
Begin
  byteReceived := 0;
  Result := 0;
  SetLength(buff, 255);

  byteReceived := self.readBuffer(buff[0], SizeOf(buff));

  If (byteReceived > 0) Then
  Begin
    SetLength(data, SizeOf(buff));
    lstrcpyn(@data[1], @buff[0], SizeOf(buff));
    Result := byteReceived;
  End
  Else If byteReceived = SOCKET_ERROR Then
    Result := SOCKET_ERROR;
End;

Function TIOHandler.readBuffer(Var buffer; bufferSize: Integer): Integer;
Begin
  Result := recv(self.ioSocket.aSock, buffer, bufferSize, 0);
End;

我得到了罕见的符号,看起来是字符编码问题。谁能告诉我哪里错了。

最好的问候。

【问题讨论】:

    标签: delphi sockets encoding character recv


    【解决方案1】:
    1. 不要使用字符数组作为缓冲区,使用“字节数组”而不是“字符数组”,它会自动使您的代码独立于字符大小。或者,您可以将 RawBinaryString 类型用于二进制数据。

    2. SizeOf(buff) 是指针的大小(4 或 8 个字节取决于目标),您应该使用类似“Length(buff)*SizeOf(buff[0])”的内容

    3. 不要忘记在新的 Delphi 编译器中 char 的大小默认为 2,强烈建议阅读有关 Delphi 中的 char/string 类型的内容。

    更新:您可以像这样转换字符串RawBinaryString:

    function BinToString(const s: RawByteString): String;
    begin
      assert(length(s) mod SizeOf(result[1])=0);
      setlength(result, length(s) div SizeOf(result[1]));
      move(s[1], result[1], length(result)*SizeOf(result[1]));
    end;
    
    function StringToBin(const s: String): RawByteString;
    begin
      setlength(result, length(s)*SizeOf(s[1]));
      move(s[1], result[1], length(result));
    end;
    

    【讨论】:

    • 感谢您的评论安德烈,我会修复它。我还想说我已经通过用 AnsiString 替换字符串解决了这个问题,所以我发送和接收 AnsiString。你有什么想法?哪个更好 ?在我的情况下是 Ansi 还是 Unicode?​​span>
    • @Samuel 在某些情况下(例如,当您分配不同类型的字符串变量时)Delphi 可以进行隐式转换,它可能会损坏保存在字符串中的二进制数据。我认为在你的情况下使用 RowBinaryString 类型而不是 AnsiString 更好(它几乎与使用字节数组相同)。而且我不知道你需要什么样的字符串,从代码看起来你使用字符串来传输二进制数据。
    • 它用于客户端/服务器应用程序。所以我将发送/接收字符串和二进制数据。我想保留字符串,但正如我之前所说,当我通过 recv() 读取字符串时会得到稀有字符。
    • @Samuel 您可以将 RawBinaryString 用于二进制数据,当您需要发送文本字符串时,您可以轻松地将其从 String 转换为 RawBinaryString,反之亦然(我添加了一个小示例)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    相关资源
    最近更新 更多