void ClientConnectCB(IAsyncResult ar) { try { //结束连接,返回的Socket其实是连接上客户端的Socket,即这个Socket可以访问到客户端的数据 Socket clientSkt = skt.EndAccept(ar); T session = new T(); //开始接受数据 session.StartRcvData(clientSkt, () => { //如果在List中已经包含了该会话,则将该会话移除 if (sessionLst.Contains(session)) { sessionLst.Remove(session); } }); //将该会话加入到list中 sessionLst.Add(session); } catch (Exception e) { PETool.LogMsg(e.Message, LogLevel.Error); } //再次开启以接收下一次的客户端访问 skt.BeginAccept(new AsyncCallback(ClientConnectCB), skt); }
/// <summary> /// Launch Client /// </summary> public void StartAsClient(string ip, int port) { try { skt.BeginConnect(new IPEndPoint(IPAddress.Parse(ip), port), new AsyncCallback(ServerConnectCB), skt); PETool.LogMsg("\nClient Start Success!\nConnecting To Server......", LogLevel.Info); } catch (Exception e) { PETool.LogMsg(e.Message, LogLevel.Error); } }
void ServerConnectCB(IAsyncResult ar) { try { skt.EndConnect(ar); session = new T(); session.StartRcvData(skt, null); } catch (Exception e) { PETool.LogMsg(e.Message, LogLevel.Error); } }
/// <summary> /// Launch Server /// </summary> public void StartAsServer(string ip, int port) { try { skt.Bind(new IPEndPoint(IPAddress.Parse(ip), port)); skt.Listen(backlog); skt.BeginAccept(new AsyncCallback(ClientConnectCB), skt); PETool.LogMsg("\nServer Start Success!\nWaiting for Connecting......", LogLevel.Info); } catch (Exception e) { PETool.LogMsg(e.Message, LogLevel.Error); } }
void ClientConnectCB(IAsyncResult ar) { try { Socket clientSkt = skt.EndAccept(ar); T session = new T(); session.StartRcvData(clientSkt); sessionLst.Add(session); } catch (Exception e) { PETool.LogMsg(e.Message, LogLevel.Error); } skt.BeginAccept(new AsyncCallback(ClientConnectCB), skt); }
private void SendCB(IAsyncResult ar) { NetworkStream ns = (NetworkStream)ar.AsyncState; try { ns.EndWrite(ar); ns.Flush(); ns.Close(); } catch (Exception e) { PETool.LogMsg("SndMsgError:" + e.Message, LogLevel.Error); } }
/// <summary> /// Launch Client /// </summary> public void StartAsClient(string ip, int port) { try { //与服务器端的BeginAccept对应,连接到服务器的IPEndPoint,并传入自身Socket skt.BeginConnect(new IPEndPoint(IPAddress.Parse(ip), port), new AsyncCallback(ServerConnectCB), skt); PETool.LogMsg("\n服务器启动成功了喵~~~\n欢迎连接到时空枢纽喵......", LogLevel.Info); } catch (Exception e) { PETool.LogMsg(e.Message, LogLevel.Error); } }
/// <summary> /// 客户端连接至服务器成功的回调函数 /// </summary> /// <param name="ar"></param> void ServerConnectCB(IAsyncResult ar) { try { //结束掉连接,连接的信息都存入了返回的IAsyncResult中 skt.EndConnect(ar); session = new T(); //准备接受数据 session.StartRcvData(skt, null); } catch (Exception e) { PETool.LogMsg(e.Message, LogLevel.Error); } }
/// <summary> /// 先接收到了数据头后,再调用接受数据身子,获得完整的数据 /// </summary> /// <param name="ar"></param> private void RcvBodyData(IAsyncResult ar) { try { PEPkg pack = (PEPkg)ar.AsyncState; int len = skt.EndReceive(ar); if (len > 0) { pack.bodyIndex += len; //同样,如果接收到的数据长度比目标数据长度要短,则继续接受直到数据完整 if (pack.bodyIndex < pack.bodyLen) { skt.BeginReceive(pack.bodyBuff, pack.bodyIndex, pack.bodyLen - pack.bodyIndex, SocketFlags.None, new AsyncCallback(RcvBodyData), pack); } else { //反序列化数据 T msg = PETool.DeSerialize <T>(pack.bodyBuff); OnReciveMsg(msg); //loop recive,重置pack的设置后,继续开始接受数据,直到关闭连接 pack.ResetData(); skt.BeginReceive( pack.headBuff, 0, pack.headLen, SocketFlags.None, new AsyncCallback(RcvHeadData), pack); } } //同样,防止空数据,要关闭连接 else { OnDisConnected(); Clear(); } } catch (Exception e) { PETool.LogMsg("RcvBodyError:" + e.Message, LogLevel.Error); } }
private void RcvHeadData(IAsyncResult ar) { try { PEPkg pack = (PEPkg)ar.AsyncState; //返回的len为该次接受数据的总长度 int len = skt.EndReceive(ar); if (len > 0) { //headIndex此时为数据的包括数据头和数据身体的总长度 pack.headIndex += len; //如果数据的总长度得到的值要比数据头默认的4个字节要短,则说明该数据连数据头都不完整,继续接受数据直到数据完整 if (pack.headIndex < pack.headLen) { skt.BeginReceive( pack.headBuff, pack.headIndex, pack.headLen - pack.headIndex, SocketFlags.None, new AsyncCallback(RcvHeadData), pack); } else { //初始化数据身体,并且再次开始接受,这次接受的目的是按照数据头指定的长度接受数据身体 pack.InitBodyBuff(); skt.BeginReceive(pack.bodyBuff, 0, pack.bodyLen, SocketFlags.None, new AsyncCallback(RcvBodyData), pack); } } //当len<=0的情况,即远程主机强制关闭了一个现有的连接,这时候服务器会疯狂接收到空数据,这时候就应该关闭掉这段Socket连接 else { //发送关闭连接的信息 OnDisConnected(); //关闭连接 Clear(); } } catch (Exception e) { PETool.LogMsg("RcvHeadError:" + e.Message, LogLevel.Error); } }
private void RcvHeadData(IAsyncResult ar) { try { PEPkg pack = (PEPkg)ar.AsyncState; if (skt.Available == 0) { OnDisConnected(); Clear(); return; } int len = skt.EndReceive(ar); if (len > 0) { pack.headIndex += len; if (pack.headIndex < pack.headLen) { skt.BeginReceive( pack.headBuff, pack.headIndex, pack.headLen - pack.headIndex, SocketFlags.None, new AsyncCallback(RcvHeadData), pack); } else { pack.InitBodyBuff(); skt.BeginReceive(pack.bodyBuff, 0, pack.bodyLen, SocketFlags.None, new AsyncCallback(RcvBodyData), pack); } } else { OnDisConnected(); Clear(); } } catch (Exception e) { PETool.LogMsg("RcvHeadError:" + e.Message, LogLevel.Error); } }
/// <summary> /// Launch Server,根据传入的ip和port(端口号)来开启服务 /// </summary> public void StartAsServer(string ip, int port) { //使用try catch语句捕捉异常防止服务器出错宕机 try { //绑定服务器Socket的IpEndPoint(ip,port),使服务器在该ip和port上建立通信,客户端连接这个ipEndPort就可以与服务端通信 skt.Bind(new IPEndPoint(IPAddress.Parse(ip), port)); //设定服务器端最大的连接队列数(这个数值的意义尚未弄明白) skt.Listen(backlog); //开始等待客户端的连接,如果连接成功,则调用回调函数,并且将服务器Socket作为参数传递进去 skt.BeginAccept(new AsyncCallback(ClientConnectCB), skt); PETool.LogMsg("\nServer Start Success!\nWaiting for Connecting......", LogLevel.Info); } catch (Exception e) { PETool.LogMsg(e.Message, LogLevel.Error); } }
public void StartRcvData(Socket skt) { try { this.skt = skt; OnConnected(); PEPkg pack = new PEPkg(); skt.BeginReceive( pack.headBuff, 0, pack.headLen, SocketFlags.None, new AsyncCallback(RcvHeadData), pack); } catch (Exception e) { PETool.LogMsg("StartRcvData:" + e.Message, LogLevel.Error); } }
private void RcvBodyData(IAsyncResult ar) { try { PEPkg pack = (PEPkg)ar.AsyncState; int len = skt.EndReceive(ar); if (len > 0) { pack.bodyIndex += len; if (pack.bodyIndex < pack.bodyLen) { skt.BeginReceive(pack.bodyBuff, pack.bodyIndex, pack.bodyLen - pack.bodyIndex, SocketFlags.None, new AsyncCallback(RcvBodyData), pack); } else { T msg = PETool.DeSerialize <T>(pack.bodyBuff); OnReciveMsg(msg); //loop recive pack.ResetData(); skt.BeginReceive( pack.headBuff, 0, pack.headLen, SocketFlags.None, new AsyncCallback(RcvHeadData), pack); } } else { OnDisConnected(); Clear(); } } catch (Exception e) { PETool.LogMsg("RcvBodyError:" + e.Message, LogLevel.Error); } }
/// <summary> /// Send binary data /// </summary> public void SendMsg(byte[] data) { NetworkStream ns = null; try { ns = new NetworkStream(skt); if (ns.CanWrite) { ns.BeginWrite( data, 0, data.Length, new AsyncCallback(SendCB), ns); } } catch (Exception e) { PETool.LogMsg("SndMsgError:" + e.Message, LogLevel.Error); } }
public void StartRcvData(Socket skt, Action closeCB) { try { this.skt = skt; this.closeCB = closeCB; OnConnected(); PEPkg pack = new PEPkg(); skt.BeginReceive( pack.headBuff, 0, pack.headLen, SocketFlags.None, RcvHeadData, pack); } catch (Exception e) { PETool.LogMsg("StartRcvData:" + e.Message, LogLevel.Error); } }
/// <summary> /// 接受数据函数,传入连接Socket和要调用的 /// </summary> /// <param name="skt"></param> /// <param name="closeCB"></param> public void StartRcvData(Socket skt, Action closeCB) { try { this.skt = skt; this.closeCB = closeCB; //连接成功时调用(发送一条连接成功的信息) OnConnected(); PEPkg pack = new PEPkg(); //开始接受数据,这次获取数据只是获取数据头,目的是为了计算出数据头指向的数据的长度 skt.BeginReceive( pack.headBuff, 0, pack.headLen, SocketFlags.None, new AsyncCallback(RcvHeadData), //传入的objcet为pack pack); } catch (Exception e) { PETool.LogMsg("StartRcvData:" + e.Message, LogLevel.Error); } }
/// <summary> /// Send binary data /// </summary> public void SendMsg(byte[] data) { try { var ns = new NetworkStream(skt); if (ns.CanWrite) { ns.BeginWrite( data, 0, data.Length, SendCB, ns); } else { ns.Close(); PETool.LogMsg("NetworkStreamError: can't write data to network stream", LogLevel.Error); } } catch (Exception e) { PETool.LogMsg("SndMsgError:" + e.Message, LogLevel.Error); } }
/// <summary> /// Disconnect network /// </summary> protected virtual void OnDisConnected() { PETool.LogMsg("Session Disconnected.", LogLevel.Info); }
/// <summary> /// Receive network message /// </summary> protected virtual void OnReciveMsg(T msg) { PETool.LogMsg("Receive Network Message.", LogLevel.Info); }
/// <summary> /// Connect network /// </summary> protected virtual void OnConnected() { PETool.LogMsg("New Seesion Connected.", LogLevel.Info); }