Socket网络编程学习笔记(5):发送和接收实体类数据
来源:互联网 发布:弘历筹码分布指标源码 编辑:程序博客网 时间:2024/05/22 05:05
转载至:http://www.cnblogs.com/licongjie/archive/2006/10/27/542024.html
Socket网络编程学习笔记(5):发送和接收实体类数据
在前面讲述的篇幅中,发送的都是文本信息,我们只要通过Encoding中的几个方法把文本转化成二进制数组就可以利用Socket来传输了,这对于一些基本的信息传输能够得到满足,但对于一些复杂的消息交流,则有些“吃力”。我们有时候会把一些信息封闭在一个类中,如果Socket能够传送类对象,那么一些复杂的问题能够通过面向对象来解决了,即方便又安全。大家都知道,要想在网络上传输信息,必须要经过序列化才行,所以在传送类对象时,首选必须对该类对象进行序列化,才能够在网络上进行传输。
序列化类对象有三种序列化方法:
1、Xml序列化
2、Binary序列化
3、Soap序列化
这几种序列化方法,运用方法相类似,只不过用到的类不一样。在这里也不一一讲述了,有兴趣的朋友可以到网上搜一搜,相信会有不少的收获。这里主要讲一下利用Soap序列化来传送消息。
1、首先我们先来建立一个实体类,用来做消息的载体
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace sbwConsole
6{
7 [Serializable]
8 public class SocketData
9 {
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 OperateType
38 {
39 get { return _operateType; }
40 set { _operateType = value; }
41 }
42 /// <summary>
43 /// 指令信息
44 /// </summary>
45 public OperateInfo OperateInfo
46 {
47 get { return _operateInfo; }
48 set { _operateInfo = value; }
49 }
50 /// <summary>
51 /// ASP数据库连接字符串
52 /// </summary>
53 public string ConnString
54 {
55 get { return _connString; }
56 set { _connString = value; }
57 }
58 /// <summary>
59 /// 子服务器IP
60 /// </summary>
61 public string ClientIP
62 {
63 get { return _clientIP; }
64 set { _clientIP = value; }
65 }
66 /// <summary>
67 /// ASP服务器IP
68 /// </summary>
69 public string ServerIP
70 {
71 get { return _serverIP; }
72 set { _serverIP = value; }
73 }
74 }
75
76 /// <summary>
77 /// 指令类型
78 /// </summary>
79 public enum OperateType
80 {
81 /// <summary>
82 /// 网站操作
83 /// </summary>
84 Web = 0,
85 /// <summary>
86 /// 升级
87 /// </summary>
88 Upgrade,
89 /// <summary>
90 /// 迁移
91 /// </summary>
92 Transfer
93 }
94
95 /// <summary>
96 /// 指令信息
97 /// </summary>
98 public enum OperateInfo
99 {
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 SendAgain
116 }
117}
118
2、发送前先把类对象进行Soap序列化
1public 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 }
通过BitConverter.GetBytes()方法可以把数据类型转化为二进制数组,从而可以在网络上传送,所以在接收的时候先接收消息长度,再通过该长度来循环读取完整的消息。
3、接收消息
1public 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 else
27 {
28 sd = null;
29 }
30 return sd;
31 }
通过sd = (SocketData)formatter.Deserialize(mem);还原数据为类对象,就可以对此类对象进行访问了。用Xml序列化或用二进制序列化也是类似,只不过把序列化的方法改一下就可以了,一般来说用二进制序列化得到的数据最小,占用带宽也最小,而用xml和Soap来序列化,都是序列化为Xml格式,所以数据比较大,占用带宽比较大。但用xml或Soap序列化,兼容性高,可以兼容不同系统之间的通信,而二进制不行。可以说各有利弊,可以根据实际情况来选择哪一种序列化。
序列化类对象有三种序列化方法:
1、Xml序列化
2、Binary序列化
3、Soap序列化
这几种序列化方法,运用方法相类似,只不过用到的类不一样。在这里也不一一讲述了,有兴趣的朋友可以到网上搜一搜,相信会有不少的收获。这里主要讲一下利用Soap序列化来传送消息。
1、首先我们先来建立一个实体类,用来做消息的载体
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace sbwConsole
6{
7 [Serializable]
8 public class SocketData
9 {
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 OperateType
38 {
39 get { return _operateType; }
40 set { _operateType = value; }
41 }
42 /// <summary>
43 /// 指令信息
44 /// </summary>
45 public OperateInfo OperateInfo
46 {
47 get { return _operateInfo; }
48 set { _operateInfo = value; }
49 }
50 /// <summary>
51 /// ASP数据库连接字符串
52 /// </summary>
53 public string ConnString
54 {
55 get { return _connString; }
56 set { _connString = value; }
57 }
58 /// <summary>
59 /// 子服务器IP
60 /// </summary>
61 public string ClientIP
62 {
63 get { return _clientIP; }
64 set { _clientIP = value; }
65 }
66 /// <summary>
67 /// ASP服务器IP
68 /// </summary>
69 public string ServerIP
70 {
71 get { return _serverIP; }
72 set { _serverIP = value; }
73 }
74 }
75
76 /// <summary>
77 /// 指令类型
78 /// </summary>
79 public enum OperateType
80 {
81 /// <summary>
82 /// 网站操作
83 /// </summary>
84 Web = 0,
85 /// <summary>
86 /// 升级
87 /// </summary>
88 Upgrade,
89 /// <summary>
90 /// 迁移
91 /// </summary>
92 Transfer
93 }
94
95 /// <summary>
96 /// 指令信息
97 /// </summary>
98 public enum OperateInfo
99 {
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 SendAgain
116 }
117}
118
2、发送前先把类对象进行Soap序列化
1public 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进行序列化。在这里还有一个细节值得一提,那就是消息边界问题的处理,这里是利用发送消息的长度方法来实现。代码如下:
1int memsize = (int)mem.Length;
2 byte[] size = BitConverter.GetBytes(memsize);
3 ns.Write(size, 0, 4);
2 byte[] size = BitConverter.GetBytes(memsize);
3 ns.Write(size, 0, 4);
通过BitConverter.GetBytes()方法可以把数据类型转化为二进制数组,从而可以在网络上传送,所以在接收的时候先接收消息长度,再通过该长度来循环读取完整的消息。
3、接收消息
1public 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 else
27 {
28 sd = null;
29 }
30 return sd;
31 }
通过sd = (SocketData)formatter.Deserialize(mem);还原数据为类对象,就可以对此类对象进行访问了。用Xml序列化或用二进制序列化也是类似,只不过把序列化的方法改一下就可以了,一般来说用二进制序列化得到的数据最小,占用带宽也最小,而用xml和Soap来序列化,都是序列化为Xml格式,所以数据比较大,占用带宽比较大。但用xml或Soap序列化,兼容性高,可以兼容不同系统之间的通信,而二进制不行。可以说各有利弊,可以根据实际情况来选择哪一种序列化。
阅读全文
0 0
- Socket网络编程学习笔记(5):发送和接收实体类数据
- Java网络编程从入门到精通(13):使用Socket类接收和发送数据
- Java网络编程(13):使用Socket类接收和发送数据
- Java网络编程从入门到精通(13):使用Socket类接收和发送数据
- Java网络编程从入门到精通(13):使用Socket类接收和发送数据
- Java网络编程从入门到精通(13):使用Socket类接收和发送数据
- 黑马程序员--Java基础学习之网络编程(TCP、UDP、Socket、模拟发送和接收数据)
- 异步 SOCKET 编程 - 发送和接收数据
- 异步 SOCKET 编程 - 发送和接收数据
- 异步SOCKET编程-发送和接收数据
- 异步 SOCKET 编程 - 发送和接收数据
- 异步 SOCKET 编程 - 发送和接收数据
- 异步SOCKET编程-发送和接收数据
- 异步SOCKET编程-发送和接收数据
- 异步 SOCKET 编程 - 发送和接收数据
- 异步SOCKET编程-发送和接收数据[转] 异步SOCKET编程-发送和接收数据[转]
- 使用Socket类接收和发送数据
- 使用Socket类接收和发送数据
- BeanFacotry和FacotryBean的区别
- 写在前面
- 嵌入式ARM交叉编译器安装
- RxJava 系列之基本语法(1)
- 解决JavaWeb中图片路径的做法
- Socket网络编程学习笔记(5):发送和接收实体类数据
- 混淆Proguard文件
- WordPress主题制作全过程(十一):制作page.php
- 视频质量诊断系统软件
- 2017四川省赛G题2017
- 观看vip电影
- 20170607学习笔记整理
- 383. Ransom Note
- Eclipse简介和使用技巧快捷方式