2013-04-18 3 views
0

Моя идея -> система клиентского сервера, обменивается текстовыми сообщениями (цепочками) через сокеты TCP. Я хочу, чтобы протокол между клиентом и сервером основывался на XML. И поскольку информация между сокетами отправляется как byte, мне нужно отдать. Итак, вот что я делаю: Класс TheMessage с имуществом типа string. Я делаю объект этого класса со строкой, которая будет отправлена ​​как свойство объекта, и сделайте ее от Object до byte[] до XmlSerialization. С другой стороны, я делаю процесс наоборот. Это, как я сериализовать и отправить от клиента к серверу:XML-сериализация объектов через сокеты

msg.Message = Console.ReadLine(); 
byte[] writeBuff = XmlRefacrotClient.ObjectToByteArray(msg); 
Stream stm = client.GetStream(); 
stm.Write(writeBuff, 0, writeBuff.Length); 

это метод я использую для сериализации:

public static byte[] ObjectToByteArray(TheMessage obj) 
{ 
    try 
    { 
     MemoryStream ms = new MemoryStream(); 
     XmlSerializer xmlS = new XmlSerializer(typeof(Message.TheMessage)); 
     XmlTextWriter xmlTW = new XmlTextWriter(ms, Encoding.UTF8); 

     xmlS.Serialize(xmlTW, obj); 
     ms = (MemoryStream)xmlTW.BaseStream; 

     return ms.ToArray(); 
    } 
    catch(Exception) 
    { 
     throw; 
    } 
} 

это, как я получаю данные на стороне сервера:

byte[] readBuff = new byte[1024]; 
s.Receive(readBuff); 
String str = (XmlRefactorServer.ByteArrayToObject(readBuff)).ToString(); 

Console.WriteLine(str); 

и это метод де-сериализации:

public static Object ByteArrayToObject(byte[] arr) 
{ 
    try 
    { 
     XmlSerializer xmlS = new XmlSerializer(typeof(Message.TheMessage)); 
     MemoryStream ms = new MemoryStream(); 
     XmlTextWriter xmlTW = new XmlTextWriter(ms, Encoding.UTF8); 

     return xmlS.Deserialize(ms); 
    } 
    catch(Exception) 
    { 
     throw; 
    } 
} 

Все проходит гладко до тех пор, return из ByteArrayToObject не method.I получить InvalidOperationException с описанием There is an error in XML document (0, 0). на return xmlS.Deserialize(ms); линии.

Любые предложения?

+0

Вы взяли массив байтов и преобразовали его в строку или что-то еще, чтобы увидеть, как это выглядит? Возможно, вы можете обнаружить ошибку в XML, если увидите, как она выглядит. – guysherman

+0

Сначала я сделал это только путем преобразования строки -> byte array -> string (для проверки самого соединения), и он работал нормально. Я получал и отправлял сообщения в обоих направлениях. – Milkncookiez

ответ

0

Попробуйте это. Это много чище:

//--------------------------------------------------------------------- 
     public static Byte[] ObjectToByteArray<T>(T obj) 
     { 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       XmlSerializer xmlS = new XmlSerializer(typeof(T)); 
       xmlS.Serialize(ms, obj); 

       return ms.ToArray(); 
      } 
     } 
     //--------------------------------------------------------------------- 
     public static T ByteArrayObject<T>(Byte[] bObj) 
     { 
      using (MemoryStream ms = new MemoryStream(bObj)) 
      { 
       XmlSerializer xmlS = new XmlSerializer(typeof(TheMessage)); 
       return (T)xmlS.Deserialize(ms); 
      } 
     } 
     //--------------------------------------------------------------------- 
     public static void Sending(Byte[] bData) 
     { 
      Stream stm = client.GetStream(); 

      // always write size first when using TCP 
      Byte[] bSize = BitConverter.GetBytes(bData.Length); 
      stm.Write(bSize, 0, bSize.Length); 
      stm.Write(bData, 0, bData.Length); 
     } 

     //--------------------------------------------------------------------- 
     public static void Receiving(Byte[] bData) 
     { 
      Byte[] bSize = new Byte[sizeof(Int32)]; 
      s.Read(bSize, 0, bSize.Length); 

      Byte[] bData = new Byte[BitConverter.ToInt32(bSize, 0)]; 
      s.Read(bData, 0, bData.Length); 

      TheMessage m = ByteArrayObject<TheMessage>(bData); 
     } 
+0

Okey, теперь это работает. За исключением того, что в 'Receiving()' вы написали 's.Read()' и 'Read()' - это метод 'NetworkStream', а не' Socket', но я создал 'NetworkStream (s)', так что это хорошо. Передача данных без ошибок, но я не получаю визуализацию текста. Я вижу, что всякий раз, когда я отправляю smth из клиента - курсор в окне консоли сервера идет по одной строке вниз, но текст не визуализируется. Это должно быть потому, что в настоящее время у меня нет данных как 'String' для записи на консоль, поэтому он просто создает новые строки. Так что, наверное, я вообще не получаю никакой информации ...? – Milkncookiez

Смежные вопросы