Tcp 数据对象传输接口对象设计

输入是一个对象inputObj,接口对象.Send(inputObj),对端接收之后解包成outputObj(与inputObj应相同),触发onPackageReceive事件

  • 事件

        public event DataServiceHandler onPackageReceived;//收包事件:

    public event DataServiceHandler onPackageSent;//发包事件:
        public event DataServiceHandler onPeerDisconnected;// 失连事件:
        public event DataServiceHandler onSendingException;//发包异常事件;
        public event DataServiceHandler onReceivingException;//收包异常时间;
        public event DataServiceHandler onNotify;//对象通知事件(通知一些状态信息什么的)

  •  成员

   SetClient()//关联Tcp连接到数据对象传输接口,复位数据对象状态,开始接收线程,允许发

   Reset()//复位数据对象状态,开始接收线程,允许发

     Stop()//停止接收线程,禁止发

         Send()//发送数据对象

 

  1 public class draftClass
  2     {
  3         #region Structure
  4         #endregion
  5 
  6         #region Fields
  7         object locker;
  8         TcpClient clientObj;
  9         Messager messager=new Messager();
 10         Thread recvThread;
 11         #endregion
 12 
 13         #region Events        
 14         public delegate void DataServiceHandler(string msg,object sender);
 15         public event DataServiceHandler onPackageReceived;
 16         public event DataServiceHandler onPackageSent;
 17         public event DataServiceHandler onPeerDisconnected;
 18         public event DataServiceHandler onSendingException;
 19         public event DataServiceHandler onReceivingException;
 20         public event DataServiceHandler onNotify;
 21         #endregion
 22 
 23         #region Functions
 24         public void SetClient(TcpClient tc)
 25         {
 26             Stop();
 27             clientObj = tc;
 28             StartReceiving();
 29         }
 30         public void ReStart()
 31         {
 32             SetClient(this.clientObj);
 33         }
 34         public void Stop() { lock (recvThread) { recvThread.Abort(); } }
 35 
 36         /// <summary>
 37         /// 打包msg和数据对象,并发送
 38         /// </summary>
 39         /// <param name="msg"></param>
 40         /// <param name="o"></param>
 41         public void Send(string msg, object o)
 42         {
 43             byte[] m = new byte[100];
 44             Encoding.UTF8.GetBytes(msg).CopyTo(m, 0);
 45             byte[] data = ObjectToBytes(o);
 46             byte[] d = new byte[m.Length + data.Length];
 47             m.CopyTo(d, 0);
 48             data.CopyTo(d, m.Length);
 49 
 50             Send(this.clientObj.GetStream(), d);
 51         }
 52         public void StartReceiving()
 53         {
 54             Thread t = new Thread(new ThreadStart(Receiving));
 55             t.Name = "[DataService] Receiving Thread";
 56             t.Start();
 57         }
 58 
 59         private void Send(NetworkStream ns, byte[] d)
 60         {
 61             lock (this)
 62             {
 63                 NetworkStream netStream = ns;
 64                 byte[] data = new byte[d.Length + 4];
 65                 System.BitConverter.GetBytes(d.Length).CopyTo(data, 0);
 66                 d.CopyTo(data, 4);
 67 
 68                 netStream.Write(data, 0, data.Length);
 69             }
 70         }
 71         private void Receiving()
 72         {
 73             {
 74                 Console.WriteLine("In Thread({0}),WaitingData", Thread.CurrentThread.ManagedThreadId);
 75                 NetworkStream ns = clientObj.GetStream();
 76                 while (IsOnline())
 77                 {
 78                     while (ns.DataAvailable)
 79                     {
 80 #if DEBUG
 81                         DateTime start = DateTime.Now;
 82 #endif
 83                         //收到的数据为2进制的原始数据,数据交给分发器处理函数
 84                         byte[] data = ReceiveByteArray(ns);
 85                         Distributor(data);
 86 #if DEBUG
 87                         TimeSpan ts = DateTime.Now - start;
 88                         double r = data.Length * 8 / (ts.TotalSeconds * 1024 * 1024);
 89                         Console.WriteLine("ReceiveByteArray Length={0}\tDuring={1:f0}ms\tRate= {2:f3} Mbps", data.Length, ts.TotalMilliseconds, r);
 90 #endif
 91                     }
 92                     //Thread.Sleep(3);
 93                 }
 94                 Console.WriteLine("In Thread({0}),clientObj Disconnect!", Thread.CurrentThread.ManagedThreadId);
 95 
 96                 if (onPeerDisconnected != null)
 97                     onPeerDisconnected("Peer Disconnected",null);
 98                 Thread.CurrentThread.Abort();
 99             }
100         }
101         //报文结构是自定义的2进制数据
102         //Part1:定长100字节,存放消息
103         //Part2:序列化了的数据对象
104         private void Distributor(byte[] data)
105         {
106             //解包
107             string msg = GetMsg(data);
108             object obj = GetObj(data);
109 
110             //msg过Messager.Paser()
111             if (messager.TryParser(msg, obj))
112                 return;
113 
114             //如果Messager处理失败,触发onPackageReceived事件
115             if (onPackageReceived != null)
116                 onPackageReceived("",data);
117         }
118         #region api 
119         private string GetMsg(byte[] data) { return ""; }
120         private object GetObj(byte[] data) {return new object(); }
121         private byte[] ReceiveByteArray(NetworkStream stream)
122         {
123             try
124             {
125                 int bufferlen = GetSize(stream);
126                 byte[] resultbyte = new byte[bufferlen];
127 
128                 int offset = 0, bytesread = 0;
129                 while (offset < bufferlen)
130                 {
131                     bytesread = stream.Read(resultbyte, offset, bufferlen - offset);
132                     if (bytesread == 0)
133                     {
134                         Console.WriteLine("?????A");
135                         throw new Exception("网络异常断开,数据读取不完整。");
136                     }
137                     else
138                         offset += bytesread;
139                 }
140                 return resultbyte;
141             }
142             catch (Exception)
143             {
144                 Console.WriteLine("?????B");
145                 throw;
146             }
147         }
148         private int GetSize(NetworkStream stream)
149         {
150             try
151             {
152                 int bufferlen = 4;
153                 byte[] resultbyte = new byte[bufferlen];
154 
155                 int offset = 0, bytesread = 0;
156                 while (offset < bufferlen)
157                 {
158                     bytesread = stream.Read(resultbyte, offset, bufferlen - offset);
159                     if (bytesread == 0)
160                         throw new Exception("网络异常断开,数据读取不完整。");
161                     else
162                         offset += bytesread;
163                 }
164                 return System.BitConverter.ToInt32(resultbyte, 0);
165             }
166             catch (Exception)
167             {
168                 throw;
169             }
170         }
171         private bool IsOnline()
172         {
173             TcpClient c = this.clientObj;
174             return !((c.Client.Poll(1000, SelectMode.SelectRead) && (c.Client.Available == 0)) || !c.Client.Connected);
175         }
176         /// <summary> 
177         /// 将一个object对象序列化,返回一个byte[]         
178         /// </summary> 
179         /// <param name="obj">能序列化的对象</param>         
180         /// <returns></returns> 
181         /// 
182         private byte[] ObjectToBytes(object obj)
183         {
184             using (MemoryStream ms = new MemoryStream())
185             {
186                 IFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, obj); return ms.GetBuffer();
187             }
188         }
189         /// <summary> 
190         /// 将一个序列化后的byte[]数组还原         
191         /// </summary>
192         /// <param name="Bytes"></param>         
193         /// <returns></returns> 
194         private object BytesToObject(byte[] Bytes)
195         {
196             using (MemoryStream ms = new MemoryStream(Bytes))
197             {
198                 IFormatter formatter = new BinaryFormatter(); return formatter.Deserialize(ms);
199             }
200         }
201         #endregion
202         #endregion
203     }
DataService.cs

 

posted on 2015-08-17 15:27  xiaoboz  阅读(835)  评论(0编辑  收藏  举报

导航