国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

Remoting中數據序列化

2024-07-21 02:25:29
字體:
來源:轉載
供稿:網友
該文講述通過網絡傳輸序列化數據的兩個類,binaryformatter和soapformatter類。這些類可以將類的實例轉化成字節流通過網絡傳輸到遠程系統,也可以轉換回原來的數據。

一、 使用序列化類

序列化一個類,并通過網絡傳輸需要三步:

1、將要序列化的類創建成一個library對象。

2、編寫一個發送程序來創建要序列化類的實例,并發送。

3、編寫一個接收程序從流中讀取數據,并重新創建原來的序列化類。

① 編寫要序列化的類

每個要通過網絡傳輸數據的類必須在原代碼文件里使用[serializable]標簽。這表明,類中所有的數據在傳輸時都將要被序列化。下面展示了如何創建一個可以序列化的類。

using system;
[serializable]
public class serialemployee
{
public int employeeid
public string lastname;
public string firstname;
public int yearsservice;
public double salary;
public serialemployee()
{
employeeid = 0;
lastname = null;
firstname = null;
yearsservice = 0;
salary = 0.0;
}
}
為了使用該類來傳輸數據,必須現創建一個library文件:

csc /t:library serialemployee.cs

② 編寫一個傳輸程序

創建數據類以后,可以創建一個程序來傳輸數據。可以使用binaryformatter和soapformatter類來序列化數據。

binaryformatter將數據序列化為二進制流。通常在實際數據中,增加一些信息,例如類名和版本號信息。

也可以使用soapformatter類使用xml格式來傳輸數據。使用xml的好處就是可以在任何系統和程序間傳遞數據。

第一必須創建一個流的實例來傳遞數據。可以是任何類型的流,包括filestream,memorystream,networkstream。然后,可以創建一個序列化類,使用serialize()方法來通過流對象傳遞數據:

stream str = new filestream( "testfile.bin", filemode.create, fileaccess.readwrite);
iformatter formatter = new binaryformatter();
formatter.serialize(str, data);

iformatter類創建了一個用來序列化的類的實例(binaryformatter或者soapformatter),使用serialize()類來將數據序列化

using system;
using system.io;
using system.runtime.serialization;
using system.runtime.serialization.formatters.soap;
class soaptest
{
public static void main()
{
serialemployee emp1 = new serialemployee();
serialemployee emp2 = new serialemployee();
emp1.employeeid = 1;
emp1.lastname = "blum";
emp1.firstname = "katie jane";
emp1.yearsservice = 12;
emp1.salary = 35000.50;
emp2.employeeid = 2;
emp2.lastname = "blum";
emp2.firstname = "jessica";
emp2.yearsservice = 9;
emp2.salary = 23700.30;
stream str = new filestream("soaptest.xml", filemode.create,
fileaccess.readwrite);
iformatter formatter = new soapformatter();
formatter.serialize(str, emp1);
formatter.serialize(str, emp2);
str.close();
}
}
soapformatter類包含在system.runtime.serialization.formatters.soap命名空間,binaryformatter類包含在system.runtime.serialization.formatters.binary命名空間,iformatter接口包含在system.runtime.serialization命名空間。

編譯代碼:csc /r:serialemployee.dll soaptest.cs

運行soaptest.exe程序后,可以查看產生的soaptest.xml文件

<soap-env:envelope xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" &acirc;
xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:soap-enc= &acirc;
"http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap-env= &acirc;
"http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr= &acirc;
"http://schemas.microsoft.com/soap/encoding/clr/1.0" soap-env:encodingstyle= &acirc;
"http://schemas.xmlsoap.org/soap/encoding/">
<soap-env:body>
<a1:serialemployee id="ref-1" xmlns:a1= &acirc;
"http://schemas.microsoft.com/clr/assem/serialemployee%2c%20version%3d0.&acirc;
0.0.0%2c%20culture%3dneutral%2c%20publickeytoken%3dnull">
<employeeid>1</employeeid>
<lastname id="ref-3">blum</lastname>
<firstname id="ref-4">katie jane</firstname>
<yearsservice>12</yearsservice>
<salary>35000.5</salary>
</a1:serialemployee>
</soap-env:body>
</soap-env:envelope>
<soap-env:envelope xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" &acirc;
xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:soap-enc= &acirc;
"http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap-env= &acirc;
"http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr= &acirc;
"http://schemas.microsoft.com/soap/encoding/clr/1.0" soap-env:encodingstyle= &acirc;
"http://schemas.xmlsoap.org/soap/encoding/">
<soap-env:body>
<a1:serialemployee id="ref-1" xmlns:a1= &acirc;
"http://schemas.microsoft.com/clr/assem/serialemployee%2c%20version%3d0.&acirc;
0.0.0%2c%20culture%3dneutral%2c%20publickeytoken%3dnull">
<employeeid>2</employeeid>
<lastname id="ref-3">blum</lastname>
<firstname id="ref-4">jessica</firstname>
<yearsservice>9</yearsservice>
<salary>23700.3</salary>
</a1:serialemployee>
</soap-env:body>
</soap-env:envelope>
查看soaptest.xml文件,我們可以發現在序列化類中soap是如何定義每個數據元素。一個值得注意的重要xml數據特點如下:

<a1:serialemployee id="ref-1" xmlns:a1= &acirc;
"http://schemas.microsoft.com/clr/assem/serialemployee%2c%20version%3d0.&acirc;0.0.0.%2c%20culture%3dneutral%2c%20publickeytoken%3dnull">
這里,xml中定義的數據使用了序列化數據類的實際類名。如果接收程序使用了另一個不同的類名,會和從流中讀取的xml數據不匹配。類不匹配,讀取將會失敗。

下面的代碼展示了如何序列化數據,將數據傳送到遠程系統。

using system;
using system.net;
using system.net.sockets;
using system.runtime.serialization;
using system.runtime.serialization.formatters.binary;
class binarydatasender
{
public static void main()
{
serialemployee emp1 = new serialemployee();
serialemployee emp2 = new serialemployee();
emp1.employeeid = 1;
emp1.lastname = "blum";
emp1.firstname = "katie jane";
emp1.yearsservice = 12;
emp1.salary = 35000.50;
emp2.employeeid = 2;
emp2.lastname = "blum";
emp2.firstname = "jessica";
emp2.yearsservice = 9;
emp2.salary = 23700.30;
tcpclient client = new tcpclient("127.0.0.1", 9050);
iformatter formatter = new binaryformatter();
networkstream strm = client.getstream();
formatter.serialize(strm, emp1);
formatter.serialize(strm, emp2);
strm.close();
client.close();
}
}
因為binaryformatter和soapformatter類需要一個stream對象來傳遞序列化的數據,所以要使用一個tcp socket對象或者一個tcpclient對象來傳遞數據,不能直接使用udp。

③編寫一個接收程序

using system;
using system.net;
using system.net.sockets;
using system.runtime.serialization;
using system.runtime.serialization.formatters.binary;
class binarydatarcvr
{
public static void main()
{
tcplistener server = new tcplistener(9050);
server.start();
tcpclient client = server.accepttcpclient();
networkstream strm = client.getstream();
iformatter formatter = new binaryformatter();
serialemployee emp1 = (serialemployee)formatter.deserialize(strm);
console.writeline("emp1.employeeid = {0}", emp1.employeeid);
console.writeline("emp1.lastname = {0}", emp1.lastname);
console.writeline("emp1.firstname = {0}", emp1.firstname);
console.writeline("emp1.yearsservice = {0}", emp1.yearsservice);
console.writeline("emp1.salary = {0}/n", emp1.salary);
serialemployee emp2 = (serialemployee)formatter.deserialize(strm);
console.writeline("emp2.employeeid = {0}", emp2.employeeid);
console.writeline("emp2.lastname = {0}", emp2.lastname);
console.writeline("emp2.firstname = {0}", emp2.firstname);
console.writeline("emp2.yearsservice = {0}", emp2.yearsservice);
console.writeline("emp2.salary = {0}", emp2.salary);
strm.close();
server.stop();
}
}

二、 程序改進

在前面的程序中有一個假設:發送者的所有數據都被接收者接收。如果數據丟失,調用deserialize()方法會發生錯誤。一個簡單的解決方法是將序列化數據放到memorystream對象中。memorystream對象將所有的序列化數據保存在內存中,可以很容易得到序列化數據的大小。當傳遞數據時,將數據大小和數據一起傳遞。

using system;
using system.io;
using system.net;
using system.net.sockets;
using system.runtime.serialization;
using system.runtime.serialization.formatters.soap;
class betterdatasender
{
public void senddata (networkstream strm, serialemployee emp)
{
iformatter formatter = new soapformatter();
memorystream memstrm = new memorystream();
formatter.serialize(memstrm, emp);
byte[] data = memstrm.getbuffer();
int memsize = (int)memstrm.length;
byte[] size = bitconverter.getbytes(memsize);
strm.write(size, 0, 4);
strm.write(data, 0, memsize);
strm.flush();
memstrm.close();
}
public betterdatasender()
{
serialemployee emp1 = new serialemployee();
serialemployee emp2 = new serialemployee();
emp1.employeeid = 1;
emp1.lastname = "blum";
emp1.firstname = "katie jane";
emp1.yearsservice = 12;
emp1.salary = 35000.50;
emp2.employeeid = 2;
emp2.lastname = "blum";
emp2.firstname = "jessica";
emp2.yearsservice = 9;
emp2.salary = 23700.30;
tcpclient client = new tcpclient("127.0.0.1", 9050);
networkstream strm = client.getstream();
senddata(strm, emp1);
senddata(strm, emp2);
strm.close();
client.close();
}
public static void main()
{
betterdatasender bds = new betterdatasender();
}
}
接收數據程序如下:

using system;
using system.io;
using system.net;
using system.net.sockets;
using system.runtime.serialization;
using system.runtime.serialization.formatters.soap;
class betterdatarcvr
{
private serialemployee recvdata (networkstream strm)
{
memorystream memstrm = new memorystream();
byte[] data = new byte[4];
int recv = strm.read(data, 0, 4);
int size = bitconverter.toint32(data, 0);
int offset = 0;
while(size > 0)
{
data = new byte[1024];
recv = strm.read(data, 0, size);
memstrm.write(data, offset, recv);
offset += recv;
size -= recv;
}
iformatter formatter = new soapformatter();
memstrm.position = 0;
serialemployee emp = (serialemployee)formatter.deserialize(memstrm);
memstrm.close();
return emp;
}
public betterdatarcvr()
{
tcplistener server = new tcplistener(9050);
server.start();
tcpclient client = server.accepttcpclient();
networkstream strm = client.getstream();
serialemployee emp1 = recvdata(strm);
console.writeline("emp1.employeeid = {0}", emp1.employeeid);
console.writeline("emp1.lastname = {0}", emp1.lastname);
console.writeline("emp1.firstname = {0}", emp1.firstname);
console.writeline("emp1.yearsservice = {0}", emp1.yearsservice);
console.writeline("emp1.salary = {0}/n", emp1.salary);
serialemployee emp2 = recvdata(strm);
console.writeline("emp2.employeeid = {0}", emp2.employeeid);
console.writeline("emp2.lastname = {0}", emp2.lastname);
console.writeline("emp2.firstname = {0}", emp2.firstname);
console.writeline("emp2.yearsservice = {0}", emp2.yearsservice);
console.writeline("emp2.salary = {0}", emp2.salary);
strm.close();
server.stop();
}
public static void main()
{
betterdatarcvr bdr = new betterdatarcvr();
}
}


收集最實用的網頁特效代碼!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 韶山市| 涿州市| 黔南| 军事| 万山特区| 淮南市| 大邑县| 南溪县| 周至县| 双辽市| 绥江县| 哈密市| 和田市| 萍乡市| 阿坝| 渭南市| 盱眙县| 榆树市| 特克斯县| 桦甸市| 焉耆| 丹东市| 河北省| 安乡县| 清涧县| 察隅县| 唐山市| 宝山区| 舞阳县| 甘洛县| 仁寿县| 辉县市| 建德市| 嘉义市| 大方县| 乌鲁木齐县| 松潘县| 镇原县| 都兰县| 凉山| 松潘县|