2016-07-26 34 views
2

我有這樣的代碼插入一些沒有拉丁字符內,然後從IDTCPserver發送到idTcpclient如何讀取從iDTCPServer發送的內存流中的非拉丁字符?

LVU := TStringList.Create; 
LVU.Add('مرحبا'); 
try 

    if (LVU.Count > 0) then 
    begin 
    memorylist := TMemoryStream.Create; 
    try 
     LVU.SaveToStream(memorylist); 
     memorylist.Position := 0; 
     AContext.Connection.IOHandler.DefStringEncoding := IndyTextEncoding_UTF8; 
     AContext.Connection.IOHandler.LargeStream := true; 
     AContext.Connection.IOHandler.Write(memorylist, 0, true); 
    finally 
     memorylist.Free; 
    end; 
    end; 
finally 
    LVU.Free; 
end; 

,但是當客戶接受它,它裏面recive MS作爲文本「???????」可能是什麼問題 ?我已經設置連接編碼爲utf8

我在Ubuntu上運行此服務器。當我在Windows上嘗試服務器時,我通常會收到文本。

這是我在客戶端讀取流

FMSFROMCALL := TMemoryStream.Create; 
FTCP.Socket.LargeStream := True; 
FTCP.Socket.ReadStream(FMSFROMCALL, -1, false); 
FMSFROMCALL.Position := 0; 

回答

7

你的DefStringEncoding分配並不適用於TIdIOHandler.Write(TStream)方法。它僅適用於在字符串< - >字節之間進行轉換的IOHandler方法,但您的TStream已經是原始字節,因此不涉及字符串轉換。

要做到你嘗試一下,你需要通過TEncoding.UTF8TStringList.SaveToStream()方法:

LVU := TStringList.Create; 
try 
    LVU.Add('مرحبا'); 
    memorylist := TMemoryStream.Create; 
    try 
    LVU.SaveToStream(memorylist, TEncoding.UTF8); 
    memorylist.Position := 0; 
    AContext.Connection.IOHandler.LargeStream := true; 
    AContext.Connection.IOHandler.Write(memorylist, 0, true); 
    finally 
    memorylist.Free; 
    end; 
finally 
    LVU.Free; 
end; 

當你不編碼傳遞給SaveToStream(),它就會使用默認的編碼,編碼而你的情況是不支持阿拉伯語的,所以這就是???????的來源。

另一種方法是發送的TIdBytes代替TMemoryStream

Bytes := IndyTextEncoding_UTF8.GetBytes('مرحبا'); 
AContext.Connection.IOHandler.WriteInt64(Length(Bytes)); 
AContext.Connection.IOHandler.Write(Bytes); 

或者只發送字符串,是DefStringEncoding分配:

s := 'مرحبا'; 
AContext.Connection.IOHandler.DefStringEncoding := IndyTextEncoding_UTF8; 
AContext.Connection.IOHandler.WriteInt64(IndyTextEncoding_UTF8.GetByteCount(s)); 
AContext.Connection.IOHandler.Write(s);