我有一个客户端服务器应用程序,我需要使用TCP连接将用户定义的对象从Client传输到Server。我的目标是以下结构:
class Conversation
{
private string convName, convOwner;
public ArrayList convUsers;
public string getConvName()
{
return this.convName;
}
public string getConvOwner()
{
return this.convOwner;
}
}
请帮助我如何从客户端传输此对象,并再次将其反序列化为服务器端的相应对象。
答案 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。