2013-10-13 60 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()讀取字符串時,會出現罕見的字符。 –