c#socket异步编程和断线重连
来源:互联网 发布:算法交易软件 编辑:程序博客网 时间:2024/04/30 02:53
最近想到要写写博客,那么就从2016的第一天开始吧。先写下c#中socket的异步编程吧,c#为socket提供了异步编程的接口我们就用这些写个自己的类吧
public class SocketWrapper { private static int len_buf; byte[] buffer; Socket commusocket = null; string _ip = ""; int _port = 4531; bool _connect = false; ManualResetEvent Timeout = new ManualResetEvent(false); public SocketWrapper(string ip,int port) //构造函数设定服务器的ip地址和端口 { _ip = ip; _port = port; len_buf = 1024; buffer = new byte[len_buf]; } public bool Socket_Create_Connect() { commusocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint Serv = new IPEndPoint(IPAddress.Parse(_ip), _port); Timeout.Reset(); try { commusocket.BeginConnect(Serv, new AsyncCallback(ConnectCallback), commusocket);//异步connect } catch(Exception exp) { StreamWriter mylog = new StreamWriter("log.txt", true); //记录日志文件 mylog.WriteLine(exp.Message + DateTime.Now.ToLocalTime().ToString()); mylog.Close(); return false; } if (Timeout.WaitOne(10000, false)) //这里等待10s或者是异步的回调函数调用Timeout.set() { if (_connect) return true; else return false; } else return false; //超时 } public bool IsConnect { get { return _connect; } set { _connect = value; } } public string SyncReceive()//同步接受 { try { string result = ""; if (commusocket == null) Socket_Create_Connect(); else if (!commusocket.Connected) //只能判断上次的连接状况 { if (!IsConnected()) { Reconnect(); } } int length = commusocket.Receive(buffer, buffer.Length, 0); if (length > 0) { int len = BitConverter.ToInt32(buffer, 0); //这里是自己定义的格式前四位表示信息长度并不包括本身这四位 result = Encoding.Unicode.GetString(buffer, 4, len); return result; } return result; } catch(Exception exp) { StreamWriter mylog = new StreamWriter("log.txt", true); //记录日志文件 mylog.WriteLine(exp.Message + DateTime.Now.ToLocalTime().ToString()); mylog.Close(); return ""; } } public bool SyncSend(byte [] buf) //同步send { try { bool result = false; if (commusocket == null) Socket_Create_Connect(); if (_connect) { int len = commusocket.Send(buf); if (len < 1) result = false; result = true; } return result; } catch(Exception exp) { StreamWriter mylog = new StreamWriter("log.txt", true); //记录日志文件 mylog.WriteLine(exp.Message + DateTime.Now.ToLocalTime().ToString()); mylog.Close(); return false; } } public void Disconnect() { commusocket.Shutdown(SocketShutdown.Both); commusocket.Disconnect(true); _connect = false; commusocket.Close(); commusocket = null; } public void Run() //这里的run可以用来循环和服务器通讯用 { IAsyncResult ar = commusocket.BeginReceive(buffer, 0, len_buf, SocketFlags.None, new AsyncCallback(CallReceive), this); } //每次服务器发送消息过来会调用beginreceive然后会调用回调函数callreceive并在这个函数里 //调用run函数就会一直监听服务器发送过来的消息 private void CallReceive(IAsyncResult ar) { try { // Socket client = (Socket)ar.AsyncState; int length = commusocket.EndReceive(ar); if(length > 0) { Receive(buffer, length); } else { if(commusocket.Connected) { Reconnect(); } } } catch(Exception exp) { StreamWriter mylog = new StreamWriter("log.txt", true); //记录日志文件 mylog.WriteLine(exp.Message + DateTime.Now.ToLocalTime().ToString()); mylog.Close(); Reconnect(); while(!_connect) { Reconnect(); Thread.Sleep(5000); //隔5秒再试 } Run(); } while(!_connect) { Reconnect(); Thread.Sleep(5000); //隔5秒再试 } Run(); } private void Receive(byte[] buf,int len) { MyEventArgs e = new MyEventArgs(); e.CommandLength = len; Array.Copy(buf,0,e.CommandBuf,0,len); OnCommandArrival(e); } private bool Reconnect() { commusocket.Shutdown(SocketShutdown.Both); commusocket.Disconnect(true); _connect = false; commusocket.Close(); return Socket_Create_Connect(); } private void ConnectCallback(IAsyncResult ar) //connect的异步回调函数 { Socket client = (Socket)ar.AsyncState; try { client.EndConnect(ar); _connect = true; } catch (Exception exp) { StreamWriter mylog = new StreamWriter("log.txt", true); //记录日志文件 mylog.WriteLine(exp.Message + DateTime.Now.ToLocalTime().ToString()); mylog.Close(); _connect = false; } finally { Timeout.Set(); //恢复信号 } } private bool IsConnected()//判断是否断线 { bool ConnectState = true; bool state = commusocket.Blocking; try { byte[] temp = new byte[1]; commusocket.Blocking = false; commusocket.Send(temp, 0, 0); ConnectState = true; } catch(SocketException e) { if (e.NativeErrorCode.Equals(10035)) //仍然是connect的 ConnectState = true; else ConnectState = false; } finally { commusocket.Blocking = state; } _connect = ConnectState; return ConnectState; } public class MyEventArgs : EventArgs //类作为委托的一个参数 { private int _command_length; private byte[] _command_buf; public MyEventArgs() { this._command_length = 0; this._command_buf = new byte[len_buf]; } public int CommandLength { get { return _command_length; } set { _command_length = value; } } public byte[] CommandBuf { get { return _command_buf; } set { _command_buf = value; } } } public delegate void CommandArrivalEventHandler(object sender, MyEventArgs args);//定义一个委托 public event CommandArrivalEventHandler CommandArrival;//用委托初始化事件 protected virtual void OnCommandArrival(MyEventArgs e)//收到服务器的命令做相应的动作 { if(CommandArrival != null) { CommandArrival(this, e); } } }
代码中的run函数用来不停的监听服务器发来的命令然后调用CallReceive函数并通过receive函数将得到的命令存放在内部类MyEventArgs中然后receive调用了OnCommandArrival这个虚函数参数就是我们的内部类。这样我们在使用时先定义一个CommandArrival(object sender, SocketWrapper.MyEventArgs e)函数
SC.CommandArrival += new SocketWrapper.CommandArrivalEventHandler(CommandArrival);
sc是类的实例这样调用sc.run()就可以实现每次服务器发送命令过来都会调用我们自己的CommandArrival的函数处理。这样就不需要自己去一直轮询
0 0
- c#socket异步编程和断线重连
- C# + Socket断线重连
- C# + Socket断线重连
- C# + Socket断线重连
- Socket 断线重连问题
- C# + Socket断线重连
- C# + Socket断线重连
- C#+Socket客户端断线重连的解决办法
- C# + Socket断线重连 整理
- C#之Socket断线重连
- Qt实现Socket断线重连机制
- 关于socket tcp 断线重连
- C# 判断Socket断线重连
- C#之Socket断线重连
- socket长连接,断线重连案例
- Qt实现Socket断线重连机制
- Windows宽带断线重连(C#)
- 长连接、心跳和断线重连
- Ubuntu安装Percona Server报libc6版本依赖错误解决方法
- 如何在eclipse中实现参数传递给args[]中
- Orb匹配算法代码
- crawler4j:轻量级多线程网络爬虫
- Stick
- c#socket异步编程和断线重连
- (转)JAVA语言为什么能跨平台?
- 怎样让FireFox显示雅黑字体
- UVa 11825 状态压缩DP
- activity互相传值报错之activity互相传值报错
- 使用python实现简单的百度百科词条爬虫
- Android Studio基本介绍
- easybcd 安装双系统文件内容
- poj1017 packets