/// <summary> /// 数据接收处理函数 /// </summary> /// <param name="iar">异步Socket</param> protected virtual void RecvData(IAsyncResult iar) { Socket remote = (Socket)iar.AsyncState; try { int recv = remote.EndReceive(iar); //正常的退出 if (recv == 0) { _session.TypeOfExit = Session.ExitType.NormalExit; if (DisConnectedServer != null) { DisConnectedServer(this, new NetEventArgs(_session)); } return; } _recvDataLength = recv; string receivedData = _coder.GetEncodingString(_recvDataBuffer, recv); //receivedData = ""; //for (int i = 0; i < recv; i++) //{ // receivedData += _recvDataBuffer[i] + ";"; //} //通过事件发布收到的报文 if (ReceivedDatagram != null) { //通过报文解析器分析出报文 //如果定义了报文的尾标记,需要处理报文的多种情况 if (_resolver != null) { if (_session.Datagram != null && _session.Datagram.Length != 0) { //加上最后一次通讯剩余的报文片断 receivedData = _session.Datagram + receivedData; } string[] recvDatagrams = _resolver.Resolve(ref receivedData); foreach (string newDatagram in recvDatagrams) { //Need Deep Copy.因为需要保证多个不同报文独立存在 ICloneable copySession = (ICloneable)_session; Session clientSession = (Session)copySession.Clone(); clientSession.Datagram = newDatagram; //发布一个报文消息 ReceivedDatagram(this, new NetEventArgs(clientSession)); } //剩余的代码片断,下次接收的时候使用 _session.Datagram = receivedData; } //没有定义报文的尾标记,直接交给消息订阅者使用 else { ICloneable copySession = (ICloneable)_session; Session clientSession = (Session)copySession.Clone(); clientSession.Datagram = receivedData; ReceivedDatagram(this, new NetEventArgs(clientSession)); } }//end of if(ReceivedDatagram != null) //继续接收数据 _session.ClientSocket.BeginReceive(_recvDataBuffer, 0, DefaultBufferSize, SocketFlags.None, new AsyncCallback(RecvData), _session.ClientSocket); } catch (SocketException ex) { //客户端退出 if (10054 == ex.ErrorCode) { //服务器强制的关闭连接,强制退出 _session.TypeOfExit = Session.ExitType.ExceptionExit; if (DisConnectedServer != null) { DisConnectedServer(this, new NetEventArgs(_session)); } } else { //throw (ex); //return; _session.TypeOfExit = Session.ExitType.ExceptionExit; if (DisConnectedServer != null) { DisConnectedServer(this, new NetEventArgs(_session)); } } } catch (ObjectDisposedException ex) { //这里的实现不够优雅 //当调用CloseSession()时,会结束数据接收,但是数据接收 //处理中会调用int recv = client.EndReceive(iar); //就访问了CloseSession()已经处置的对象 //我想这样的实现方法也是无伤大雅的. if (ex != null) { ex = null; //DoNothing; } } }
/// <summary> /// 发送数据 /// </summary> /// <param name="recvDataClient">接收数据的客户端会话</param> /// <param name="datagram">数据报文</param> public virtual void Send(Session recvDataClient, string datagram) { //获得数据编码 byte[] data = _coder.GetEncodingBytes(datagram); recvDataClient.ClientSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendDataEnd), recvDataClient.ClientSocket); }
/// <summary> /// 接受数据完成处理函数,异步的特性就体现在这个函数中, /// 收到数据后,会自动解析为字符串报文 /// </summary> /// <param name="iar">目标客户端Socket</param> protected virtual void ReceiveData(IAsyncResult iar) { Socket client = (Socket)iar.AsyncState; try { //如果两次开始了异步的接收,所以当客户端退出的时候 //会两次执行EndReceive int recv = client.EndReceive(iar); if (recv == 0) { //正常的关闭 CloseClient(client, Session.ExitType.NormalExit); return; } string receivedData = _coder.GetEncodingString(_recvDataBuffer, recv); byte[] receiveBytes = new byte[recv - 1]; Array.Copy(_recvDataBuffer, 1, receiveBytes, 0, recv - 1); ReceivedBytes = receiveBytes; //发布收到数据的事件 if (RecvData != null) { Session sendDataSession = FindSession(client); Trace.Assert(sendDataSession != null); //如果定义了报文的尾标记,需要处理报文的多种情况 if (_resolver != null) { if (sendDataSession.Datagram != null && sendDataSession.Datagram.Length != 0) { //加上最后一次通讯剩余的报文片断 receivedData = sendDataSession.Datagram + receivedData; } string[] recvDatagrams = _resolver.Resolve(ref receivedData); foreach (string newDatagram in recvDatagrams) { //深拷贝,为了保持Datagram的对立性 ICloneable copySession = (ICloneable)sendDataSession; Session clientSession = (Session)copySession.Clone(); clientSession.Datagram = newDatagram; //发布一个报文消息 RecvData(this, new NetEventArgs(clientSession)); } //剩余的代码片断,下次接收的时候使用 sendDataSession.Datagram = receivedData; if (sendDataSession.Datagram.Length > MaxDatagramSize) { sendDataSession.Datagram = null; } } //没有定义报文的尾标记,直接交给消息订阅者使用 else { ICloneable copySession = (ICloneable)sendDataSession; Session clientSession = (Session)copySession.Clone(); clientSession.Datagram = receivedData; RecvData(this, new NetEventArgs(clientSession)); } }//end of if(RecvData!=null) //继续接收来自来客户端的数据 client.BeginReceive(_recvDataBuffer, 0, _recvDataBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveData), client); } catch (SocketException ex) { //客户端退出 if (10054 == ex.ErrorCode) { //客户端强制关闭 CloseClient(client, Session.ExitType.ExceptionExit); } } catch (ObjectDisposedException ex) { //这里的实现不够优雅 //当调用CloseSession()时,会结束数据接收,但是数据接收 //处理中会调用int recv = client.EndReceive(iar); //就访问了CloseSession()已经处置的对象 //我想这样的实现方法也是无伤大雅的. if (ex != null) { ex = null; //DoNothing; } } }
/// <summary> /// 返回两个Session是否代表同一个客户端 /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { Session rightObj = (Session)obj; return((int)_cliSock.Handle == (int)rightObj.ClientSocket.Handle); }