程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Socket網絡編程學習筆記(5):發送和接收實體類數據

Socket網絡編程學習筆記(5):發送和接收實體類數據

編輯:關於.NET

在前面講述的篇幅中,發送的都是文本信息,我們只要通過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    }

這裡利用

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);
   通過 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. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved