/// <summary> /// 由Server.Update来调用,经过KCP处理后,如果确认是客户端发来的信息,则调用m_KCPServer.OnRecvData /// </summary> /// GG:修改代码采用回调,不直接调用 m_KCPServer internal void process_recv_queue(SocketAsyncEventArgs e) { #if DEV IRQLog.AppLog.Log(this.m_netIndex.ToString() + ",接收1"); #endif m_Kcp.Input(e.Buffer, e.Offset, e.BytesTransferred); m_NeedUpdateFlag = true; for (var size = m_Kcp.PeekSize(); size > 0; size = m_Kcp.PeekSize()) { byte[] buffer; buffer = (UdpLibConfig.UseBytePool ? m_KCPServer.BytePool.Rent(size) : new byte[size]); try { if (m_Kcp.Recv(buffer) > 0) { m_LastRecvTimestamp = m_KCPServer.m_watch.Elapsed; uint key = 0; KCPLib.ikcp_decode32u(buffer, 0, ref key); if (m_KCPServer.IsClientKeyCorrect(this.m_netIndex, (int)key) == false) { #if DEBUG Console.WriteLine("index:{0} key 不对", this.m_netIndex); #endif m_KCPServer.BytePool.Return(buffer, true); DisposeReason = ClientSessionDisposeReason.IndexKeyError; //key不对 Dispose(); return; } #if DEV IRQLog.AppLog.Log(this.m_netIndex.ToString() + ",接收2"); #endif m_KCPServer.OnRecvData(this, buffer, 0, size); } } finally { if (UdpLibConfig.UseBytePool) { m_KCPServer.BytePool.Return(buffer, true); } } } }
/// <summary> /// 仅仅在UpdateRepeatedly里面调用。 /// 如果是握手信息,则创建Session,并返回握手应答;否则让ClientSession自己处理。 /// </summary> private void ProcessRecvQueue() { mRecvQueue.Switch(); while (!mRecvQueue.Empty()) { var e = mRecvQueue.Pop(); if (e.BytesTransferred == 0) { //说明客户端关闭了,GG:UDP不知道客户端关闭的事情吧? PushSAE(e); continue; } uint index; if (TryProcessHandShake(e, out index)) { continue; } try { KCPLib.ikcp_decode32u(e.Buffer, e.Offset, ref index); var clientSession = GetSession(index); if (clientSession != null && clientSession.Status == ClientSessionStatus.Connected) { Debug.Assert(clientSession.EndPoint.ToString() == e.RemoteEndPoint.ToString()); //c.EndPoint = e.RemoteEndPoint; clientSession.process_recv_queue(e); } } finally { //GG: 使用Disposeale将PushSAE放在一起。简化代码。 PushSAE(e); } } }
private bool TryProcessHandShake(SocketAsyncEventArgs e, out uint index) { index = 0; uint key = 0; //使用纯udp进行握手,8字节0xFF+4字节conv+4字节key if (!IsHandshake(e.Buffer, e.Offset, e.BytesTransferred, out index, out key)) { return(false); } var c = GetSession(index); uint cc = 0; KCPLib.ikcp_decode32u(e.Buffer, e.Offset + 16, ref cc); if (c == null) { //新连接处理,如果返回false,则不予处理,可以用来进行非法连接的初步处理 if (NewSessionProcessor != null && !NewSessionProcessor.OnNewSession(index, e.RemoteEndPoint)) { PushSAE(e); return(true); } c = AddSession(e.RemoteEndPoint, index); c.m_KCPServer = this; c.m_LastRecvTimestamp = m_watch.Elapsed; NewClientSession?.Invoke(c, e.Buffer, e.Offset, e.BytesTransferred); #if DEV IRQLog.AppLog.Log(index.ToString() + ",连接1," + cc.ToString()); #endif } else { #if DEV IRQLog.AppLog.Log(index.ToString() + ",连接2," + cc.ToString()); #endif c.EndPoint = e.RemoteEndPoint; //如果客户端关闭并且立刻重连,这时候是连不上的,因为KCP中原有的数据不能正确处理 //c.ResetKCP(); //GG: 待处理。 } c.Status = ClientSessionStatus.Connected; //回发握手请求 if (UdpLibConfig.ServerSendAsync) { m_UdpSocket.SendToAsync(e); } else { #if DEBUG Stopwatch sw = Stopwatch.StartNew(); m_UdpSocket.SendTo(e.Buffer, e.Offset, e.BytesTransferred, SocketFlags.None, e.RemoteEndPoint); Console.WriteLine((sw.ElapsedTicks * 1000f / Stopwatch.Frequency)); #else m_UdpSocket.SendTo(e.Buffer, e.Offset, e.BytesTransferred, SocketFlags.None, e.RemoteEndPoint); #endif PushSAE(e); } #if DEV IRQLog.AppLog.Log(index.ToString() + ",发送数据UDP"); #endif return(true); }
private void ProcessRecvQueue() { mRecvQueue.Switch(); while (!mRecvQueue.Empty()) { var e = mRecvQueue.Pop(); if (e.BytesTransferred == 0) { PushSAE(e); //说明客户端关闭了 continue; } uint index = 0, key = 0; //使用纯udp进行握手,8字节0xFF+4字节conv+4字节key if (IsHandshake(e.Buffer, e.Offset, e.BytesTransferred, out index, out key)) { var c = GetSession(index); uint cc = 0; KCPLib.ikcp_decode32u(e.Buffer, e.Offset + 16, ref cc); if (c == null) { bool add = true; //新连接处理,如果返回false,则不予处理,可以用来进行非法连接的初步处理 if (NewSessionProcessor != null) { add = NewSessionProcessor.OnNewSession(index, e.RemoteEndPoint); } if (add == false) { PushSAE(e); continue; } c = AddSession(e.RemoteEndPoint, index); c.m_KCPServer = this; c.m_LastRecvTimestamp = m_watch.Elapsed; OnNewClientSession(c, e.Buffer, e.Offset, e.BytesTransferred); #if DEV IRQLog.AppLog.Log(index.ToString() + ",连接1," + cc.ToString()); #endif } else { #if DEV IRQLog.AppLog.Log(index.ToString() + ",连接2," + cc.ToString()); #endif c.EndPoint = e.RemoteEndPoint; //如果客户端关闭并且立刻重连,这时候是连不上的,因为KCP中原有的数据不能正确处理 //c.ResetKCP(); } c.Status = ClientSessionStatus.Connected; //回发握手请求 if (UdpLibConfig.ServerSendAsync) { m_UdpSocket.SendToAsync(e); } else { #if DEBUG Stopwatch sw = Stopwatch.StartNew(); m_UdpSocket.SendTo(e.Buffer, e.Offset, e.BytesTransferred, SocketFlags.None, e.RemoteEndPoint); Console.WriteLine((sw.ElapsedTicks * 1000f / Stopwatch.Frequency)); #else m_UdpSocket.SendTo(e.Buffer, e.Offset, e.BytesTransferred, SocketFlags.None, e.RemoteEndPoint); #endif PushSAE(e); } #if DEV IRQLog.AppLog.Log(index.ToString() + ",发送数据UDP"); #endif } else { try { KCPLib.ikcp_decode32u(e.Buffer, e.Offset, ref index); var c = GetSession(index); if (c != null && c.Status == ClientSessionStatus.Connected) { Debug.Assert(c.EndPoint.ToString() == e.RemoteEndPoint.ToString()); //c.EndPoint = e.RemoteEndPoint; c.process_recv_queue(e); } } finally { PushSAE(e); } } } }