2013-10-13 129 views
2

我最近将Delphi 7 IDE更改为Delphi XE5(Big change)。我正在研究一个小型客户端/服务器应用程序,并且在尝试读取字符串时遇到问题。在Delphi中使用Socket Recv方法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; 

我得到难得的符号,看起来就像是字符编码的问题。谁能告诉我哪个是我错了。

此致敬礼。

回答

3
  1. 唐使用炭用于缓冲的阵列,使用“字节的数组”,而不是“char数组”,它会自动使独立于炭的大小的代码。或者,您可以使用RawBinaryString类型来获取二进制数据。

  2. 一下SizeOf(浅黄色)是指针的大小(4或取决于目标的8个字节),则应该使用类似 “长度(BUFF)*一下SizeOf(抛光轮[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; 
+0

感谢您的评论安德烈,我会解决它。我也想说,我已经通过用AnsiString替换字符串来解决问题,所以我发送和接收AnsiString。你有什么想法?哪个更好 ? Ansi或Unicode在我的情况? –

+1

@Samuel在某些情况下(例如,当你指定不同类型的字符串变量时)Delphi可以做隐式转换,它可能损坏保存在字符串中的二进制数据。我认为最好在你的情况下使用RowBinaryString类型而不是AnsiString(它与使用字节数组几乎相同)。而且我不知道你需要什么样的字符串,从代码看起来你使用字符串来传输二进制数据。 –

+0

它适用于客户端/服务器应用程序。所以我会发送/接收字符串和二进制数据。我想保留字符串,但正如我之前所说的,当我通过recv()读取字符串时,会出现罕见的字符。 –