2016-09-13 53 views
0

我使用TcpClient和TcpListener類在兩個應用程序之間交換一些對象。我使用XML序列化(請參閱下面的代碼)。基本上一切工作正常。問題是,當一個應用程序在短時間內發送多個對象時,我在接收端的MemoryStream中有多個對象(多個根元素,也帶有XML版本標籤)。我如何處理所有對象,以及如何處理所有對象?我可以將列表中的對象分組,並將序列化爲整個列表,但遲早我會面臨同樣的問題。 這看起來像我認爲的一個常見問題,但我還沒有找到解決方案。從具有多個對象的流反序列化

對象序列化:

public class DataModel 
{ 
    public string Command { get; set; } 
    public string Value { get; set; } 

    // ctor etc 
} 

接收方:

private void onRead(IAsyncResult ar) 
    {  

     int nBytes = _client.GetStream().EndRead(ar); 

     XmlSerializer serializer = new XmlSerializer(typeof(DataModel)); 
     MemoryStream memStream = new MemoryStream(buffer); 
     DataModel dmo = (DataModel)serializer.Deserialize(memStream); 
     buffer = new byte[1024]; 
     _client.GetStream().BeginRead(buffer, 0, buffer.Length, new AsyncCallback(onRead), null); 

     // read on if more available... 

    } 

示例流內容:

<?xml version="1.0"?> 
<DataModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Command>XXX</Command> 
    <Value>1.0</Value> 
</DataModel><?xml version="1.0"?> 
<DataModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Command>XXX</Command> 
    <Value>5</Value> 
</DataModel><?xml version="1.0"?> 
<DataModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Command>XXX</Command> 
    <Value>YYY</Value> 
</DataModel> 

我刪除的try/catch,調試的東西,一切不必要的

+0

無論何時發送數據,您都需要使用以下一種或多種技術來終止每條消息:1)ASCII:使用消息中未使用的已知字符終止每條消息2)ASCII或二進制:向具有字節數的消息添加前綴。 3)Ascii或Binary:發送修復長度消息。在你的情況下,我會用ETX(0x03)或EOT(0x04)等字符來終止每個DataModel元素。然後在保存xml之前刪除字符。分別處理每個元素。 – jdweng

回答

0

首先,你是否同意這種模式?也許其他應用程序有一個錯誤,應該分別發送每個Xml文檔。在哪個陣容中,這不是你需要解決的問題。

但是,如果你也同意這一點,或正在使用的持久連接:

你的問題是不是真的與XML相關。您可以通過打開的連接傳送任何類型的內容。

問題是你不能'正確'入流。

您已經從流中分別讀取了每個單獨的XmlDocument,每個XmlDocument都放入它自己的內部流中。然後你可以做任何你想要的,因爲它現在是有效的Xml。

您可以逐字節讀取數據,查找聲明以指示下一個文檔,也可以使用XmlReader,也可以測試下一個聲明,否則會引發異常。

相關問題