10

के साथ त्रुटि क्या किसी को कॉम्पैक्ट फ्रेमवर्क और पूर्ण नेट फ्रेमवर्क के बीच क्रमबद्ध/deserialize करने के लिए ProtoBuf-Net का उपयोग करते समय किसी भी समस्या से अवगत है? मेरे पास लॉगडाटा नामक एक कक्षा है जिसे मैं कॉम्पैक्ट फ्रेमवर्क 3.5 के तहत क्रमबद्ध कर रहा हूं, एक सर्वर (नेट फ्रेमवर्क 4.0 चला रहा है) को ट्रांसमिट कर रहा हूं, जो तब deserializes। कभी-कभी यह काम करता है और कभी-कभी यह उपरोक्त त्रुटि को फेंक देता है और मैंने इसे अभी तक किसी विशिष्ट कारण से सीमित नहीं किया है। मैंने अलग-अलग मानों के साथ कई सारे परीक्षण किए हैं और त्रुटि होने पर कोई कविता या कारण नहीं दिख रहा है। मैं नीचे अपनी कक्षाएं शामिल कर रहा हूं (विभिन्न रचनाकारों को घटाएं)। मैंने कई मौकों पर किसी भी तरफ बाइट बफर को देखा है और तार पर एक तरफ से दूसरे तरफ भेजे गए डेटा में अंतर नहीं मिला है।"स्रोत डेटा में अमान्य फ़ील्ड: 0" प्रोटोबफ-नेट और कॉम्पैक्ट फ्रेमवर्क

[ProtoContract] 
public class LogData 
{ 

    [ProtoContract] 
    public enum LogSeverity 
    { 
    [ProtoEnum(Name = "Information", Value = 0)] 
    Information, 
    [ProtoEnum(Name = "Warning", Value = 1)] 
    Warning, 
    [ProtoEnum(Name = "Error", Value = 2)] 
    Error, 
    [ProtoEnum(Name = "Critical", Value = 3)] 
    Critical 
    } 

    [ProtoMember(1)] 
    public string UserID { get; set; } 
    [ProtoMember(2)] 
    public string ComputerName { get; set; } 
    [ProtoMember(3)] 
    public ExceptionProxy Exception { get; set; } 
    [ProtoMember(4)] 
    public LogData.LogSeverity Severity { get; set; } 
    [ProtoMember(5)] 
    public string Source { get; set; } 
    [ProtoMember(6)] 
    public string Caption { get; set; } 
    [ProtoMember(7)] 
    public string Description { get; set; } 
    [ProtoMember(8)] 
    public DateTime TimeOfOccurrence { get; set; } 
    [ProtoMember(9)] 
    public Guid SessionID { get; set; } 
    [ProtoMember(10)] 
    public string MethodName { get; set; } 
    [ProtoMember(11)] 
    public string OSVersion { get; set; } 
    [ProtoMember(12)] 
    public string Category { get; set; } 
    [ProtoMember(13)] 
    public string Location { get; set; } 
} 

[ProtoContract] 
public class ExceptionProxy 
{ 

    [ProtoMember(1)] 
    public Type ExceptionType { get; set; } 
    [ProtoMember(2)] 
    public string Message { get; set; } 
    [ProtoMember(3)] 
    public string StackTrace { get; set; } 
    [ProtoMember(4)] 
    public ExceptionProxy InnerException { get; set; } 

} 

यहाँ मेरी कोड है कि क्रमबद्धता और

private void WriteLogDataToServer(LogData data) 
    { 
    using (var client = new TcpClient()) 
    { 
     client.Connect(Host, SignalLineServerPort); 
     using (var stream = client.GetStream()) 
     { 
      using (var ms = new MemoryStream()) 
      { 
       Serializer.Serialize<LogData>(ms, data); 
       var buffer = ms.GetBuffer(); 
       int position = 0; 
       WriteFrameMarkers(stream); 
       byte[] frameLengthBuffer = BitConverter.GetBytes(buffer.Length); 
       stream.Write(frameLengthBuffer, 0, IntByteSize); 
       while (position < buffer.Length) 
       { 
       int length = Math.Min(ChunkSize, buffer.Length - position); 
       stream.Write(buffer, position, length); 
       position += ChunkSize; 
       } 
      } 
     } 
     client.Close(); 
    }   
    } 

भेजने करता है और यह कोड है कि सर्वर पर डाटा रीड

public override LogData ReadData(NetworkStream stream) 
    { 
    if (stream.DataAvailable) 
    { 
     try 
     { 
      const int chunkSize = 250; 
      byte[] buffer = new byte[IntByteSize]; 
      int messageSize = 0; 
      int totalBytesRead = 0; 
      LogData data; 
      using (var ms = new MemoryStream()) 
      { 
       if (!ReadFrameMarkers(stream)) 
       return null; 
       totalBytesRead = stream.Read(buffer, 0, IntByteSize); 
       if (totalBytesRead != IntByteSize) 
       return null; 
       messageSize = BitConverter.ToInt32(buffer, 0); 
       totalBytesRead = 0; 
       while ((totalBytesRead < messageSize)) 
       { 
       int bufferSize = Math.Min(chunkSize, messageSize - totalBytesRead); 
       buffer = new byte[bufferSize]; 
       int bytesRead = stream.Read(buffer, 0, bufferSize); 
       if (bytesRead != 0) 
       { 
        totalBytesRead += bytesRead; 
        ms.Write(buffer, 0, bytesRead); 
       } 
       } 
       ms.Seek(0, SeekOrigin.Begin); 
       data = Serializer.Deserialize<LogData>(ms); 
      } 
      return data; 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(string.Format("Error occurred: {0}", ex.Message)); 
      return null; 
     } 
    } 
    return null; 
    } 
+1

क्या मैं उस कोड को देख सकता हूं जिसका आप उपयोग कर रहे हैं: serialize, तार को भेजें, तार से पढ़ें, deserialize? मेरी मजबूत शर्त यह है कि पढ़ने के लिए लंबाई सीमित किए बिना, आपने गलती से बफर में कुछ 0 पैडिंग छोड़ी थी। –

+0

मैंने सीरियलाइज और deserialize कोड शामिल करने के लिए पोस्ट संपादित किया। मैंने तारों के कोड को छोड़ दिया जो कनेक्शन की स्वीकृति की बातचीत को संभालने में कामयाब रहा। अगर आपको कोड पर कोई और जानकारी चाहिए तो मुझे बताएं। बहुत बहुत धन्यवाद मार्क। – WiredWiz

उत्तर

13

आसान एक है: आप का उपयोग करें:

var buffer = ms.GetBuffer(); 

और फिर buffer.Length। इसका मतलब है कि आप oversized, गद्देदार बफर का उपयोग कर रहे हैं। यदि आप ऐसा करते हैं तो आपको ms.Length का उपयोग करने की आवश्यकता है, जो आपको वास्तविक लंबाई बताएगा। वैकल्पिक रूप से, ms.ToArray() का उपयोग किया जा सकता है, लेकिन इसमें एक अतिरिक्त प्रति शामिल है।

मेरी सलाह: GetBuffer() का उपयोग करते रहें, लेकिन केवल ms.Length बाइट्स लिखें, बफर नहीं। लम्बाई बाइट्स।

एक बार जब आप इन अतिरिक्त गलत शून्य को हटा देते हैं, तो मुझे उम्मीद है कि आपको यह काम मिल जाएगा।

+0

धन्यवाद मार्क, यदि आप त्रि-राज्य क्षेत्र में हैं तो मैं आपको कुछ पेय देता हूं। यह मजाकिया है कि सरल चीजें सबसे निराशाजनक कैसे होती हैं। – WiredWiz

+0

@WiredWiz तुमने मुझे अभी याद किया! मैं वहां एक सप्ताह पहले था। लेकिन अब नहीं; पी –

+0

ग्रेट टिप, धन्यवाद। –

0

मुझे एहसास हुआ कि मुख्य डेवलपर @MarcGravell पहले से ही उत्तर दिया है, लेकिन मैं सिर्फ अपना खुद का $ 0.02 साझा करना चाहता था जिसने मुझे इस मुद्दे पर मदद की। अगर मेरे पास एक निश्चित आकार बाइट है [] और बदले में पढ़ने वाले बाइट्स की गिनती प्राप्त करें, तो मैं बस मेमोरीस्ट्रीम घोषणा में निर्दिष्ट कर सकता हूं और यह समस्या हल करता है। साथ ही, जैसा कि यह ओपी पर लागू होता है, जब तक आप पढ़ा नहीं जाता तब तक मेमोरीस्ट्रीम घोषित न करें।

byte[] msg = new byte[4096]; 
int bytesRead = someStreamClass.Read(msg, 0, 4096); 
using (MemoryStream ms = new MemoryStream(msg, 0, bytesRead)) 
{  
    logData = Serializer.Deserialize<LogData>(ms); 
} 

@MarcGravell: इस महान पुस्तकालय के लिए धन्यवाद!

संबंधित मुद्दे