打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
C#用XML方法通过网络发送对象(包含私有数据)的方法

C#用XML方法通过网络发送对象(包含私有数据)的方法


作者:李英林 日期:2010-04-14


代码下载:
服务器端代码: SERVER-Program.rar
客户端代码:  Client.rar
一:服务器端代码,测试时首先要运行。可以在同台本地计算机上测试。

//提供使用XML方法,我们可以在采用不同语言编写的程序之间来回发送对象,
//而且从理论上讲还可以在不同平台之间发送对象。
/*
对   象 
....|
....|
客   户<------- XML文档--------> 服务器

*/
/*
System.Xml.XmlSerialize命名空间提供了一个功能非常强大的工具集,可以把对象串行化到XML中。把对象串行化和反串行化到XML中替代了把对象保存为二进制格式,因此可以通过XML对对象进行其他处理。这将大大增强设计的灵活性。
串行化是把一个对象存入磁盘的过程。应用程序的另一部分,甚至另一个应用程序都可以反串行化对象,使它的状态与串行化之前相同。.NET Framework为此提供了两种方式。
本节将介绍System.Xml.Serialization命名空间。它包含的类可用于把对象串行化为XML文档或流。这表示对象的公共属性和公共字段将转换为XML元素和/或属性。 
System.Xml.Serialization命名空间中最重要的类是XmlSerializer。要串行化对象,首先需要实例化一个XmlSerializer对象,指定要串行化的对象类型,然后实例化一个流/写入器对象,把文件写入流/文档。最后一步是在XmlSerializer上调用Serializer()方法,给它传送流/写入器对象和要串行化的对象。 
被串行化的数据可以为基本类型的数据、字段、数组和XmlElements和XmlAttribute对象格式的内嵌XML。 
为了从XML文档中反串行化对象,应执行上述过程的逆过程。即创建一个流/读取器对象和一个XmlSerializer对象,然后给DeSerializer()方法传送该流/读取器对象。这个方法返回反串行化的对象,但需要转换为正确的类型。
注意: 
XML串行化器不能转换私有数据,只能转换公共数据,它也不能串行化对象图表。
但是,这并不是一个严格的限制。对类进行仔细设计,就很容易避免突破这个限制。如果需要串行化公共数据和私有数据,以及包含许多嵌套对象的对象图形,就可以使用System. Runtime. Serialization. Formatters.Binary命名空间。 
使用System.Xml.Serialization类可以进行的其他工作如下所示: 
●   确定数据应是一个属性还是元素
●   指定命名空间
●   改变属性或元素名
对象和XML文档之间的链接是给类加上注释的定制C#属性,这些属性可以告诉串行化程序如何写入数据。.
* XmlSerializer类的Serialize方法实际执行串行化,它有6个重载方法。第一个重载方法的参数是要写入数据的流,可以是Stream、TextWriter或XmlWriter。在本例中, 
* 创建了一个基于CheckingAccount的对象myRestoredAccount。接着创建了基于XmlSerializer的对象myXmlfactory。XmlSerializer需要知道要串行化的对象的类型信息,
* 所以对要串行化的类型使用typeof关键字。在创建myXmlfactory对象后,调用Serialize方法,其参数是myRestoredAccount(基于Stream的对象)和要串行化的对象,确保完成后关闭该数据流。
该示例中服务器,对它进行反串行化.字段是private,只能通过CheckingAccount类中的get和set方法来访问 
IP:
127.0.0.1是一个回送地址,这说明客户将要连接的服务器就是本机。
任意值11111是指定的虚拟端口,服务器必须监听这个端口
一旦客户与服务器建立了合法的通信,而且发送并获取了对象,客户就将终止。
首先要确认服务器端已经运行

本程序也讲到了手动抛出异常的方法
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Serialization;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Server
{
//定义对象CheckingAccount
[XmlRoot("account")]
public class CheckingAccount
{
private String strName;
//private int intAccountNyumber;
/// <summary>
/// Accessor method for strName
/// </summary>
[XmlElement("name")]
public String Name
{
get { return strName; }
set { strName = value; }
}
/// <summary>
/// Accessory Methods for intAccountNumber
/// </summary>
//[XmlElement("account_num")]
//public int AccountNumber
//{
//   get { return intAccountNyumber; }
//   set { AccountNumber = value; }   //堆栈溢出错误???StackOverflowException 因执行堆栈溢出错误引发,不知原因
//}
//从 .NET Framework 2.0 版开始,将无法通过try-catch 块捕获StackOverflowException 对象,并且默认情况下将终止相应的进程。

/// <summary>
/// Defaultr constructor
/// </summary>
public CheckingAccount()
{
this.Name = "John Doe";
//this.AccountNumber = 54321;
Console.WriteLine("Creating Checking Account!");
}
}
class Server
{

//创建checkingAccount对象引用 
//连接到scoket并监听;  
//建立输入流; 
//创建流 
//从流读取字节; 
//将对象串行化至流; 
//关闭所有资源; 

public Server()
{
TcpListener server = null;
TcpClient client = null;
try
{
//Creat our Socket Listener and strta it
server = new TcpListener(IPAddress.Parse("127.0.0.1"), 11111); );//两个参数表示IP地址和虚拟端口 
//127.0.0.1是一个回送地址,这说明客户将要连接的服务器就是本机。
//任意值11111是指定的虚拟端口,服务器必须监听这个端口
//一旦客户与服务器建立了合法的通信,而且发送并获取了对象,客户就将终止。
//首先要确认服务器端已经运行

server.Start();
//Setup our input buffer
Byte[] bytes = new Byte[256];
//Loop indefuntely
while (true)
{
//Begain accepting incoming transmission in block mode
client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
//Open our stream
NetworkStream stream = client.GetStream();
//Read all the data from the stream
int i;
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
//Prepare a format that the serializer can read
MemoryStream ms = new MemoryStream(bytes);
//Pepare the serializer
XmlSerializer myXmlfactory = new XmlSerializer(typeof(CheckingAccount));
//Creat our CheckingAccount from the etream
CheckingAccount myRestoredAccount = (CheckingAccount)myXmlfactory.Deserialize(ms);
//Now demonstrate that the object is indeed created
Console.WriteLine("Name: {0},Account Number: {1}.", myRestoredAccount.Name, 0/*myRestoredAccount.AccountNumber*/);//AccountNumber StackOverflowException 因执行堆栈溢出错误引发,因此以0替代,不知原因 
//Throw aN EXCEPTION TO EXIT THE LOOP
throw new Exception("ignore");
}
}
}
catch (Exception ex)
{
if (!ex.Message.Equals("ignore"))
{
Console.WriteLine("Exception: {0}", ex);
}
}
finally
{
//Close our resources
client.Close();
server.Stop();
}
}
}

class Program
{
static void Main(string[] args)
{
Server server=new Server ();
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
}


二、客户端代码。 

//提供使用XML方法,我们可以在采用不同语言编写的程序之间来回发送对象,
//而且从理论上讲还可以在不同平台之间发送对象。
/*
对   象 
....|
....|
客   户<------- XML文档--------> 服务器

*/
/*
System.Xml.XmlSerialize命名空间提供了一个功能非常强大的工具集,可以把对象串行化到XML中。把对象串行化和反串行化到XML中替代了把对象保存为二进制格式,因此可以通过XML对对象进行其他处理。这将大大增强设计的灵活性。
串行化是把一个对象存入磁盘的过程。应用程序的另一部分,甚至另一个应用程序都可以反串行化对象,使它的状态与串行化之前相同。.NET Framework为此提供了两种方式。
本节将介绍System.Xml.Serialization命名空间。它包含的类可用于把对象串行化为XML文档或流。这表示对象的公共属性和公共字段将转换为XML元素和/或属性。 
System.Xml.Serialization命名空间中最重要的类是XmlSerializer。要串行化对象,首先需要实例化一个XmlSerializer对象,指定要串行化的对象类型,然后实例化一个流/写入器对象,把文件写入流/文档。最后一步是在XmlSerializer上调用Serializer()方法,给它传送流/写入器对象和要串行化的对象。 
被串行化的数据可以为基本类型的数据、字段、数组和XmlElements和XmlAttribute对象格式的内嵌XML。 
为了从XML文档中反串行化对象,应执行上述过程的逆过程。即创建一个流/读取器对象和一个XmlSerializer对象,然后给DeSerializer()方法传送该流/读取器对象。这个方法返回反串行化的对象,但需要转换为正确的类型。
注意: 
XML串行化器不能转换私有数据,只能转换公共数据,它也不能串行化对象图表。
但是,这并不是一个严格的限制。对类进行仔细设计,就很容易避免突破这个限制。如果需要串行化公共数据和私有数据,以及包含许多嵌套对象的对象图形,就可以使用System. Runtime. Serialization. Formatters.Binary命名空间。 
使用System.Xml.Serialization类可以进行的其他工作如下所示: 
●   确定数据应是一个属性还是元素
●   指定命名空间
●   改变属性或元素名
对象和XML文档之间的链接是给类加上注释的定制C#属性,这些属性可以告诉串行化程序如何写入数据。.
* XmlSerializer类的Serialize方法实际执行串行化,它有6个重载方法。第一个重载方法的参数是要写入数据的流,可以是Stream、TextWriter或XmlWriter。在本例中, 
* 创建了一个基于CheckingAccount的对象myRestoredAccount。接着创建了基于XmlSerializer的对象myXmlfactory。XmlSerializer需要知道要串行化的对象的类型信息,
* 所以对要串行化的类型使用typeof关键字。在创建myXmlfactory对象后,调用Serialize方法,其参数是myRestoredAccount(基于Stream的对象)和要串行化的对象,确保完成后关闭该数据流。
该示例中服务器,对它进行反串行化.字段是private,只能通过CheckingAccount类中的get和set方法来访问 
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Net;
using System.Net.Sockets;
//using System.Text;
namespace Client
{
//定义对象CheckingAccount
[XmlRoot("account")]
public class CheckingAccount
{
private String strName;
private int intAccountNyumber;
/// <summary>
/// Accessor method for strName
/// </summary>
[XmlElement ("name")]
public String Name
{
get { return strName ;}
set{strName =value ;}
}
/// <summary>
/// Accessory Methods for intAccountNumber
/// </summary>
[XmlElement("account_num")]
public int AccountNumber
{
get{return intAccountNyumber ;}
set{intAccountNyumber =value ;}
}
/// <summary>
/// Defaultr constructor
/// </summary>
public CheckingAccount()
{
this .Name ="Kinglion";
this.AccountNumber=54321;
Console .WriteLine ("Creating Checking Account!");
}
}

class Client
{
//创建checkingAccount对象 
//创建scoket;
//将对象串行化为XML; 
//创建流; 
//将对象串行化至流; 
//关闭资源; 
//关闭流 
public void Connect()   //static
{
try
{
CheckingAccount myAccount=new CheckingAccount ();


//Creat our TCP Socket
TcpClient client=new TcpClient ("127.0.0.1",11111);//两个参数表示IP地址和虚拟端口 
//127.0.0.1是一个回送地址,这说明客户将要连接的服务器就是本机。
//任意值11111是指定的虚拟端口,服务器必须监听这个端口
//一旦客户与服务器建立了合法的通信,而且发送并获取了对象,客户就将终止。
//首先要确认服务器端已经运行
//Prepare to serialize our CheckingAccount object to XML
XmlSerializer myXmlFactory=new XmlSerializer (typeof (CheckingAccount ));
//Create our TCP Stream
NetworkStream stream=client .GetStream();
//Serialize our object to the TCP Stream
myXmlFactory .Serialize (stream ,myAccount );
//Close all of our resources
stream .Close();
client .Close();
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
catch (Exception ex)
{
Console .WriteLine("Exception: {0}",ex);  
}
}


static void Main(string[] args)
{

Client client=new Client ();
client.Connect();

//Console.WriteLine("Press any key to continue...");
//Console.ReadKey();
}
}
}


运行结果: 
首先启动服务器端程序:SERVER,
然后运行客户端程序:CLIENT, 


服务器端显示: 

Connected!
Creating Checking Account!
Name: Kinglion,Account Number: 0.
Press any key to continue...

运行客户端程序:CLIENT
客户端显示: 

Creating Checking Account!
Press any key to continue...

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
深入C#学习系列一:序列化(Serialize)、反序列化(Deserialize)
C# 串行化
XML与对象的序列化与反序列化
序列化
C# 类串行化 Serialize
C#对象与XMl文件之间的相互转换
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服