void init_kcp(UInt32 conv) { m_Kcp = new KCPLib(conv, (byte[] buf, int size) => { m_UdpClient.Send(buf, size); }); // fast mode. m_Kcp.NoDelay(1, 10, 2, 1); m_Kcp.WndSize(128, 128); }
void init_kcp(UInt32 conv) { m_Kcp = new KCPLib(conv, (byte[] buf, int size) => { m_KCPServer.Send(this, buf, 0, size); }); // fast mode. m_Kcp.NoDelay(1, 10, 2, 1); m_Kcp.WndSize(128, 128); }
/// <summary> /// 发送数据。发送时,默认在头部加上4字节的key /// </summary> /// <param name="buf"></param> public void Send(byte[] buf) { byte[] newbuf = new byte[buf.Length + 4]; //把key附上,服务端合法性检测用 KCPLib.ikcp_encode32u(newbuf, 0, (uint)m_Key); Array.Copy(buf, 0, newbuf, 4, buf.Length); m_Kcp.Send(newbuf); m_NeedUpdateFlag = true; var e = Event; if (e != null) { e(UdpClientEvents.Send, buf); } }
/// <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); } } } }
//发送握手数据 16字节 8字节头+4字节index+4字节key private void SendHandshake() { if (UdpLibConfig.DebugLevel != (int)UdpLibLogLevel.None) { #if DEBUG Console.WriteLine("发送握手数据"); #endif } Interlocked.Increment(ref m_pktCounter); byte[] buf = new byte[UdpLibConfig.HandshakeDataSize + 4]; Array.Copy(UdpLibConfig.HandshakeHeadData, buf, UdpLibConfig.HandshakeHeadData.Length); KCPLib.ikcp_encode32u(buf, UdpLibConfig.HandshakeHeadData.Length, m_NetIndex); KCPLib.ikcp_encode32u(buf, UdpLibConfig.HandshakeHeadData.Length + 4, (uint)m_Key); KCPLib.ikcp_encode32u(buf, UdpLibConfig.HandshakeHeadData.Length + 8, (uint)m_pktCounter); m_UdpClient.Send(buf, buf.Length); #if DEV string s = string.Format("{0},发送握手数据,{1}", m_NetIndex, m_pktCounter.ToString()); IRQLog.AppLog.Log(s); Console.WriteLine(s); #endif }
/// <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); } } } }