输入是一个对象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} During={1:f0}ms Rate= {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 }