作者:licongjie 来源:博客园 酷勤网收集 2007-09-05
摘要
大家都知道,要想在网络上传输信息,必须要经过序列化才行,所以在传送类对象时,首选必须对该类对象进行序列化,才能够在网络上进行传输。这里主要讲一下利用Soap序列化来传送消息。
序列化类对象有三种序列化方法:
1、Xml序列化
2、Binary序列化
3、Soap序列化
这几种序列化方法,运用方法相类似,只不过用到的类不一样。在这里也不一一讲述了,有兴趣的朋友可以到网上搜一搜,相信会有不少的收获。这里主要讲一下利用Soap序列化来传送消息。
1、首先我们先来建立一个实体类,用来做消息的载体
1
using System;2
using System.Collections.Generic;3
using System.Text;4

5
namespace sbwConsole6


{7
[Serializable]8
public class SocketData9

{10
private OperateType _operateType;11
private OperateInfo _operateInfo;12
private string _connString;13
private string _clientIP;14
private string _serverIP;15

16

/**//// <summary>17
/// 指令传输数据18
/// </summary>19
/// <param name="operateType">指令类型</param>20
/// <param name="operateInfo">指令信息</param>21
/// <param name="connString">ASP数据库连接字符串</param>22
/// <param name="clientIP">子服务器IP</param>23
/// <param name="serverIP">ASP服务器IP</param>24
public SocketData(OperateType operateType, OperateInfo operateInfo,25
string connString, string clientIP, string serverIP)26

{27
_operateType = operateType;28
_operateInfo = operateInfo;29
_connString = connString;30
_clientIP = clientIP;31
_serverIP = serverIP;32
}33

34

/**//// <summary>35
/// 指令类型36
/// </summary>37
public OperateType OperateType38

{39

get
{ return _operateType; }40

set
{ _operateType = value; }41
}42

/**//// <summary>43
/// 指令信息44
/// </summary>45
public OperateInfo OperateInfo46

{47

get
{ return _operateInfo; }48

set
{ _operateInfo = value; }49
}50

/**//// <summary>51
/// ASP数据库连接字符串52
/// </summary>53
public string ConnString54

{55

get
{ return _connString; }56

set
{ _connString = value; }57
}58

/**//// <summary>59
/// 子服务器IP60
/// </summary>61
public string ClientIP62

{63

get
{ return _clientIP; }64

set
{ _clientIP = value; }65
}66

/**//// <summary>67
/// ASP服务器IP68
/// </summary>69
public string ServerIP70

{71

get
{ return _serverIP; }72

set
{ _serverIP = value; }73
}74
}75

76

/**//// <summary>77
/// 指令类型78
/// </summary>79
public enum OperateType80

{81

/**//// <summary>82
/// 网站操作83
/// </summary>84
Web = 0,85

/**//// <summary>86
/// 升级87
/// </summary>88
Upgrade,89

/**//// <summary>90
/// 迁移91
/// </summary>92
Transfer93
}94

95

/**//// <summary>96
/// 指令信息97
/// </summary>98
public enum OperateInfo99

{100

/**//// <summary>101
/// 发送102
/// </summary>103
Send = 0,104

/**//// <summary>105
/// 出错106
/// </summary>107
Error,108

/**//// <summary>109
/// 成功110
/// </summary>111
Success,112

/**//// <summary>113
/// 重发114
/// </summary>115
SendAgain116
}117
}118

2、发送前先把类对象进行Soap序列化
1
public static void Send(NetworkStream ns, SocketData sd)2

{3
IFormatter formatter = new SoapFormatter();4
MemoryStream mem = new MemoryStream();5

6
formatter.Serialize(mem, sd);7
byte[] data = mem.GetBuffer();8
int memsize = (int)mem.Length;9
byte[] size = BitConverter.GetBytes(memsize);10
ns.Write(size, 0, 4);11
ns.Write(data, 0, memsize);12
ns.Flush();13
mem.Close();14
}
这里利用
IFormatter formatter = new SoapFormatter();
MemoryStream mem = new MemoryStream();
formatter.Serialize(mem, sd);
对类对象sd进行序列化。在这里还有一个细节值得一提,那就是消息边界问题的处理,这里是利用发送消息的长度方法来实现。代码如下:
1
int memsize = (int)mem.Length;
2
byte[] size = BitConverter.GetBytes(memsize);
3
ns.Write(size, 0, 4);
int memsize = (int)mem.Length;2
byte[] size = BitConverter.GetBytes(memsize);3
ns.Write(size, 0, 4);通过BitConverter.GetBytes()方法可以把数据类型转化为二进制数组,从而可以在网络上传送,所以在接收的时候先接收消息长度,再通过该长度来循环读取完整的消息。
3、接收消息
1
public static SocketData Receive(NetworkStream ns)2

{3
MemoryStream mem = new MemoryStream();4
SocketData sd;5
byte[] data = new byte[4];6
int revc = ns.Read(data, 0, 4);7
int size = BitConverter.ToInt32(data, 0);8
int offset = 0;9

10
if (size > 0)11

{12
while (size > 0)13

{14
data = new byte[1024];15
revc = ns.Read(data, offset, size);16
mem.Write(data, offset, revc);17
offset += revc;18
size -= revc;19
}20

21
IFormatter formatter = new SoapFormatter();22
mem.Position = 0;23
sd = (SocketData)formatter.Deserialize(mem);24
mem.Close();25
}26
else27

{28
sd = null;29
}30
return sd;31
}
通过sd = (SocketData)formatter.Deserialize(mem);还原数据为类对象,就可以对此类对象进行访问了。用Xml序列化或用二进制序列化也是类似,只不过把序列化的方法改一下就可以了,一般来说用二进制序列化得到的数据最小,占用带宽也最小,而用xml和Soap来序列化,都是序列化为Xml格式,所以数据比较大,占用带宽比较大。但用xml或Soap序列化,兼容性高,可以兼容不同系统之间的通信,而二进制不行。可以说各有利弊,可以根据实际情况来选择哪一种序列化。
该篇暂时就写到这里了,文字有点乱,请见谅。
源码下载:SocketTest4.rar
原文链接:http://www.cnblogs.com/licongjie/archive/2006/10/27/542024.html

