Передача сложных объектов с использованием TCP - PullRequest
3 голосов
/ 12 апреля 2010

У меня есть клиент-серверное приложение, в котором мне нужно передать определенный пользователем объект с клиента на сервер, используя TCP-соединение. Мой объект имеет следующую структуру:

class Conversation
{
    private string convName, convOwner;
    public ArrayList convUsers;

    public string getConvName()
    {
       return this.convName;
    }
    public string getConvOwner()
    {
       return this.convOwner;
    }
}

Пожалуйста, помогите мне, как передать этот объект от клиента и снова десериализовать его в соответствующий объект на стороне сервера.

Ответы [ 3 ]

4 голосов
/ 12 апреля 2010

Один хороший способ действий состоит в том, чтобы представить этот объект как DataContract для такой среды, как WCF, и использовать соответствующие транспорты , доступные в этой среде.

Например:

[DataContract]
class Conversation
{
    private string convName, convOwner;
    public ArrayList convUsers;

    [DataMember]
    public string ConvName
    {
       get { return this.convName; }
    }
    [DataMember]
    public string ConvOwner
    {
       get { return this.convOwner; }
    }
}
4 голосов
/ 12 апреля 2010

После ответа вы должны сделать ваш объект сериализуемым. После того, как вы сделали это с атрибутом Serializable, вы можете использовать знаменитый BinaryFormatter для преобразования вашего объекта в массив byte.

Вы можете найти множество примеров использования BinaryFormatter, просто используйте вашу любимую поисковую систему. Вот краткий пример:

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public class SerializationUtils
{
    public static byte[] SerializeToByteArray(object request)
    {
        byte[] result;
        BinaryFormatter serializer = new BinaryFormatter();
        using (MemoryStream memStream = new MemoryStream())
        {
            serializer.Serialize(memStream, request);
            result = memStream.GetBuffer();
        }
        return result;
    }

    public static T DeserializeFromByteArray<T>(byte[] buffer)
    {
        BinaryFormatter deserializer = new BinaryFormatter();
        using (MemoryStream memStream = new MemoryStream(buffer))
        {
            object newobj = deserializer.Deserialize(memStream);
            return (T)newobj;
        }
    }
}

Что касается вашего класса, он включает в себя два приватных поля. Я не вижу, где вы устанавливаете значения для них, поэтому я немного изменил ваш код, чтобы их можно было установить в конструкторе. Кроме того, я добавил необходимый атрибут Serializable:

using System;
using System.Collections;

[Serializable]
public class Conversation
{
    public Conversation(string convName, string convOwner)
    {
        this.convName = convName;
        this.convOwner = convOwner;
    }

    public Conversation()
    {
    }

    private string convName, convOwner;
    public ArrayList convUsers;

    public string getConvName()
    {
        return this.convName;
    }
    public string getConvOwner()
    {
        return this.convOwner;
    }
}

Теперь давайте соберем все вместе и увидим, что ваш класс сериализован, а затем десериализован в консольном приложении:

using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace Capishi
{
    [Serializable]
    public class Conversation
    {
        public Conversation(string convName, string convOwner)
        {
            this.convName = convName;
            this.convOwner = convOwner;
        }

        public Conversation()
        {
        }

        private string convName, convOwner;
        public ArrayList convUsers;

        public string getConvName()
        {
            return this.convName;
        }
        public string getConvOwner()
        {
            return this.convOwner;
        }
    }

    public class SerializationUtils
    {
        public static byte[] SerializeToByteArray(object request)
        {
            byte[] result;
            BinaryFormatter serializer = new BinaryFormatter();
            using (MemoryStream memStream = new MemoryStream())
            {
                serializer.Serialize(memStream, request);
                result = memStream.GetBuffer();
            }
            return result;
        }

        public static T DeserializeFromByteArray<T>(byte[] buffer)
        {
            BinaryFormatter deserializer = new BinaryFormatter();
            using (MemoryStream memStream = new MemoryStream(buffer))
            {
                object newobj = deserializer.Deserialize(memStream);
                return (T)newobj;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // create and initialize a conversation object
            var convName = "Capishi";
            var convOwner = "Ice Cream";
            Conversation myConversation = new Conversation(convName, convOwner);
            myConversation.convUsers = new ArrayList();
            myConversation.convUsers.Add("Ron Klein");
            myConversation.convUsers.Add("Rakesh K");

            // serialize to a byte array
            byte[] data = SerializationUtils.SerializeToByteArray(myConversation);

            // print the resulting byte array if you want
            // PrintArray(data);

            // deserialize the object (on the other side of the communication
            Conversation otherConversation = SerializationUtils.DeserializeFromByteArray<Conversation>(data);

            // let's see if all of the members are really there
            Console.WriteLine("*** start output ***");
            Console.WriteLine("otherConversation.getConvName() = " + otherConversation.getConvName());
            Console.WriteLine("otherConversation.getConvOwner() = " + otherConversation.getConvOwner());
            Console.WriteLine("otherConversation.convUsers:");
            foreach (object item in otherConversation.convUsers)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("*** done output ***");

            // wait before close
            Console.ReadLine();

        }

        /// <summary>
        /// just a helper function to dump an array to the console's output
        /// </summary>
        /// <param name="data"></param>
        private static void PrintArray(byte[] data)
        {
            for (int i = 0; i < data.Length; i++)
            {
                Console.Write("{0:000}", data[i]);
                if (i < data.Length - 1)
                    Console.Write(", ");
            }
            Console.WriteLine();
        }
    }
}

Результат:

*** start output ***
otherConversation.getConvName() = Capishi
otherConversation.getConvOwner() = Ice Cream
otherConversation.convUsers:
Ron Klein
Rakesh K
*** done output ***

И последнее замечание:

Я бы использовал общий List вместо устаревшего ArrayList, если только вы не привязаны к .NET 1. *.

2 голосов
/ 12 апреля 2010

Вам нужно сделать свой объект сериализуемым .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...