Tcp 数据对象传输接口对象设计
2015-08-17 15:27
585 查看
输入是一个对象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()//发送数据对象
DataService.cs
事件
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()//发送数据对象
public class draftClass { #region Structure #endregion #region Fields object locker; TcpClient clientObj; Messager messager=new Messager(); Thread recvThread; #endregion #region Events public delegate void DataServiceHandler(string msg,object sender); public event DataServiceHandler onPackageReceived; public event DataServiceHandler onPackageSent; public event DataServiceHandler onPeerDisconnected; public event DataServiceHandler onSendingException; public event DataServiceHandler onReceivingException; public event DataServiceHandler onNotify; #endregion #region Functions public void SetClient(TcpClient tc) { Stop(); clientObj = tc; StartReceiving(); } public void ReStart() { SetClient(this.clientObj); } public void Stop() { lock (recvThread) { recvThread.Abort(); } } /// <summary> /// 打包msg和数据对象,并发送 /// </summary> /// <param name="msg"></param> /// <param name="o"></param> public void Send(string msg, object o) { byte[] m = new byte[100]; Encoding.UTF8.GetBytes(msg).CopyTo(m, 0); byte[] data = ObjectToBytes(o); byte[] d = new byte[m.Length + data.Length]; m.CopyTo(d, 0); data.CopyTo(d, m.Length); Send(this.clientObj.GetStream(), d); } public void StartReceiving() { Thread t = new Thread(new ThreadStart(Receiving)); t.Name = "[DataService] Receiving Thread"; t.Start(); } private void Send(NetworkStream ns, byte[] d) { lock (this) { NetworkStream netStream = ns; byte[] data = new byte[d.Length + 4]; System.BitConverter.GetBytes(d.Length).CopyTo(data, 0); d.CopyTo(data, 4); netStream.Write(data, 0, data.Length); } } private void Receiving() { { Console.WriteLine("In Thread({0}),WaitingData", Thread.CurrentThread.ManagedThreadId); NetworkStream ns = clientObj.GetStream(); while (IsOnline()) { while (ns.DataAvailable) { #if DEBUG DateTime start = DateTime.Now; #endif //收到的数据为2进制的原始数据,数据交给分发器处理函数 byte[] data = ReceiveByteArray(ns); Distributor(data); #if DEBUG TimeSpan ts = DateTime.Now - start; double r = data.Length * 8 / (ts.TotalSeconds * 1024 * 1024); Console.WriteLine("ReceiveByteArray Length={0}\tDuring={1:f0}ms\tRate= {2:f3} Mbps", data.Length, ts.TotalMilliseconds, r); #endif } //Thread.Sleep(3); } Console.WriteLine("In Thread({0}),clientObj Disconnect!", Thread.CurrentThread.ManagedThreadId); if (onPeerDisconnected != null) onPeerDisconnected("Peer Disconnected",null); Thread.CurrentThread.Abort(); } } //报文结构是自定义的2进制数据 //Part1:定长100字节,存放消息 //Part2:序列化了的数据对象 private void Distributor(byte[] data) { //解包 string msg = GetMsg(data); object obj = GetObj(data); //msg过Messager.Paser() if (messager.TryParser(msg, obj)) return; //如果Messager处理失败,触发onPackageReceived事件 if (onPackageReceived != null) onPackageReceived("",data); } #region api private string GetMsg(byte[] data) { return ""; } private object GetObj(byte[] data) {return new object(); } private byte[] ReceiveByteArray(NetworkStream stream) { try { int bufferlen = GetSize(stream); byte[] resultbyte = new byte[bufferlen]; int offset = 0, bytesread = 0; while (offset < bufferlen) { bytesread = stream.Read(resultbyte, offset, bufferlen - offset); if (bytesread == 0) { Console.WriteLine("?????A"); throw new Exception("网络异常断开,数据读取不完整。"); } else offset += bytesread; } return resultbyte; } catch (Exception) { Console.WriteLine("?????B"); throw; } } private int GetSize(NetworkStream stream) { try { int bufferlen = 4; byte[] resultbyte = new byte[bufferlen]; int offset = 0, bytesread = 0; while (offset < bufferlen) { bytesread = stream.Read(resultbyte, offset, bufferlen - offset); if (bytesread == 0) throw new Exception("网络异常断开,数据读取不完整。"); else offset += bytesread; } return System.BitConverter.ToInt32(resultbyte, 0); } catch (Exception) { throw; } } private bool IsOnline() { TcpClient c = this.clientObj; return !((c.Client.Poll(1000, SelectMode.SelectRead) && (c.Client.Available == 0)) || !c.Client.Connected); } /// <summary> /// 将一个object对象序列化,返回一个byte[] /// </summary> /// <param name="obj">能序列化的对象</param> /// <returns></returns> /// private byte[] ObjectToBytes(object obj) { using (MemoryStream ms = new MemoryStream()) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, obj); return ms.GetBuffer(); } } /// <summary> /// 将一个序列化后的byte[]数组还原 /// </summary> /// <param name="Bytes"></param> /// <returns></returns> private object BytesToObject(byte[] Bytes) { using (MemoryStream ms = new MemoryStream(Bytes)) { IFormatter formatter = new BinaryFormatter(); return formatter.Deserialize(ms); } } #endregion #endregion }
DataService.cs
相关文章推荐
- LINUX使用FTP搭建网络版YUM源
- c 语言实现httpclient端的post,get, delete
- ZOJ 3818 Pretty Poem (2014年牡丹江赛区网络赛J题)
- 设计管理员表;webservice用于网络安全的高端内提供服务的
- 黑马程序员--java基础--网络编程TCP传输
- HTTP 状态消息和六种请求方式
- Alamofire-Swift Networking网络库
- asp.net mvc 5.0 借助路由规则实现*.aspx与HttpHandler交互
- android 缓存网络音频播放
- jason解析
- 黑马程序员-Java基础:网络编程
- Ubuntu 网卡桥接及桥接后网络不通的解决方法
- 网络编程学习之TCP客户端与服务器端
- TCP/IP协议三次握手与四次握手流程解析
- cisco 动态路由RIP配置
- HttpURLConnection 乱码
- http://www.cnblogs.com/dudu/archive/2011/03/05/asp_net_webform_mvc.html
- 在android用Get方式发送http请求
- iscsi网络存储LVM逻辑卷和RAID5卷
- 高性能、高并发、高扩展性和可读性的网络服务器架构:StateThreads