你的分享就是我们的动力 ---﹥

Socket网络编程学习笔记(5):发送和接收实体类数据

时间:2013-05-24 14:37来源:www.chengxuyuans.com 点击:
在前面讲述的篇幅中,发送的都是文本信息,我们只要通过Encoding中的几个方法把文本转化成二进制数组就可以利用Socket来传输了,这对于一些基本的信息传输能够得到满足,但对于一些复杂的消息交流,则有些“吃力”。我们有时候会把一些信息封闭在一个类中,如果Socket能够传送类对象,那么一些复杂的问题能够通过面向对象来解决了,即方便又安全。大家都知道,要想在网络上传输信息,必须要经过序列化才行,所以在传送类对象时,首选必须对该类对象进行序列化,才能够在网络上进行传输。

序列化类对象有三种序列化方法:

1、Xml序列化

2、Binary序列化

3、Soap序列化

这几种序列化方法,运用方法相类似,只不过用到的类不一样。在这里也不一一讲述了,有兴趣的朋友可以到网上搜一搜,相信会有不少的收获。这里主要讲一下利用Soap序列化来传送消息。

1、首先我们先来建立一个实体类,用来做消息的载体
类对象
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Text;
4
5namespacesbwConsole
6{
7[Serializable]
8publicclassSocketData
9{
10privateOperateType_operateType;
11privateOperateInfo_operateInfo;
12privatestring_connString;
13privatestring_clientIP;
14privatestring_serverIP;
15
16/**////<summary>
17///指令传输数据
18///</summary>
19///<paramname="operateType">指令类型</param>
20///<paramname="operateInfo">指令信息</param>
21///<paramname="connString">ASP数据库连接字符串</param>
22///<paramname="clientIP">子服务器IP</param>
23///<paramname="serverIP">ASP服务器IP</param>

24publicSocketData(OperateTypeoperateType,OperateInfooperateInfo,
25stringconnString,stringclientIP,stringserverIP)
26{
27_operateType=operateType;
28_operateInfo=operateInfo;
29_connString=connString;
30_clientIP=clientIP;
31_serverIP=serverIP;
32}

33
34/**////<summary>
35///指令类型
36///</summary>

37publicOperateTypeOperateType
38{
39get{return_operateType;}
40set{_operateType=value;}
41}

42/**////<summary>
43///指令信息
44///</summary>

45publicOperateInfoOperateInfo
46{
47get{return_operateInfo;}
48set{_operateInfo=value;}
49}

50/**////<summary>
51///ASP数据库连接字符串
52///</summary>

53publicstringConnString
54{
55get{return_connString;}
56set{_connString=value;}
57}

58/**////<summary>
59///子服务器IP
60///</summary>

61publicstringClientIP
62{
63get{return_clientIP;}
64set{_clientIP=value;}
65}

66/**////<summary>
67///ASP服务器IP
68///</summary>

69publicstringServerIP
70{
71get{return_serverIP;}
72set{_serverIP=value;}
73}

74}

75
76/**////<summary>
77///指令类型
78///</summary>

79publicenumOperateType
80{
81/**////<summary>
82///网站操作
83///</summary>

84Web=0,
85/**////<summary>
86///升级
87///</summary>

88Upgrade,
89/**////<summary>
90///迁移
91///</summary>

92Transfer
93}

94
95/**////<summary>
96///指令信息
97///</summary>

98publicenumOperateInfo
99{
100/**////<summary>
101///发送
102///</summary>

103Send=0,
104/**////<summary>
105///出错
106///</summary>

107Error,
108/**////<summary>
109///成功
110///</summary>

111Success,
112/**////<summary>
113///重发
114///</summary>

115SendAgain
116}

117}

118

2、发送前先把类对象进行Soap序列化

消息发送方法
1publicstaticvoidSend(NetworkStreamns,SocketDatasd)
2{
3IFormatterformatter=newSoapFormatter();
4MemoryStreammem=newMemoryStream();
5
6formatter.Serialize(mem,sd);
7byte[]data=mem.GetBuffer();
8intmemsize=(int)mem.Length;
9byte[]size=BitConverter.GetBytes(memsize);
10ns.Write(size,0,4);
11ns.Write(data,0,memsize);
12ns.Flush();
13mem.Close();
14}


这里利用
IFormatter formatter = new SoapFormatter();
MemoryStream mem = new MemoryStream();

formatter.Serialize(mem, sd);
对类对象sd进行序列化。在这里还有一个细节值得一提,那就是消息边界问题的处理,这里是利用发送消息的长度方法来实现。代码如下:

1intmemsize=(int)mem.Length;
2byte[]size=BitConverter.GetBytes(memsize);
3ns.Write(size,0,4);

通过BitConverter.GetBytes()方法可以把数据类型转化为二进制数组,从而可以在网络上传送,所以在接收的时候先接收消息长度,再通过该长度来循环读取完整的消息。

3、接收消息
接收消息方法
1publicstaticSocketDataReceive(NetworkStreamns)
2{
3MemoryStreammem=newMemoryStream();
4SocketDatasd;
5byte[]data=newbyte[4];
6intrevc=ns.Read(data,0,4);
7intsize=BitConverter.ToInt32(data,0);
8intoffset=0;
9
10if(size>0)
11{
12while(size>0)
13{
14data=newbyte[1024];
15revc=ns.Read(data,offset,size);
16mem.Write(data,offset,revc);
17offset+=revc;
18size-=revc;
19}

20
21IFormatterformatter=newSoapFormatter();
22mem.Position=0;
23sd=(SocketData)formatter.Deserialize(mem);
24mem.Close();
25}

26else
27{
28sd=null;
29}

30returnsd;
31}

通过sd = (SocketData)formatter.Deserialize(mem);还原数据为类对象,就可以对此类对象进行访问了。用Xml序列化或用二进制序列化也是类似,只不过把序列化的方法改一下就可以了,一般来说用二进制序列化得到的数据最小,占用带宽也最小,而用xml和Soap来序列化,都是序列化为Xml格式,所以数据比较大,占用带宽比较大。但用xml或Soap序列化,兼容性高,可以兼容不同系统之间的通信,而二进制不行。可以说各有利弊,可以根据实际情况来选择哪一种序列化。

转载注明地址:http://www.chengxuyuans.com/J2ME/61970.html

推荐文章