使用TCP传输复杂对象

时间:2010-04-12 04:07:12

标签: c# tcp

我有一个客户端服务器应用程序,我需要使用TCP连接将用户定义的对象从Client传输到Server。我的目标是以下结构:

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

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

请帮助我如何从客户端传输此对象,并再次将其反序列化为服务器端的相应对象。

3 个答案:

答案 0 :(得分:4)

一个好的做法是将此对象作为DataContract公开给像WCF这样的框架,并使用该框架中可用的appropriate transports

例如:

[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; }
    }
}

答案 1 :(得分:4)

如上所述,您应该使您的对象可序列化。使用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 :(得分:2)

您需要制作对象serializable