public override void Update() { this.Recv(); this.TimerOut(); foreach (long id in updateChannels) { KChannel kChannel = this.Get(id); if (kChannel == null) { continue; } if (kChannel.Id == 0) { continue; } kChannel.Update(); } this.updateChannels.Clear(); this.RemoveConnectTimeoutChannels(); }
protected override void Send(long channelId, long actorId, MemoryStream stream) { KChannel channel = this.Get(channelId); if (channel == null) { return; } channel.Send(actorId, stream); }
private static int KcpOutput(IntPtr bytes, int len, IntPtr kcp, IntPtr user) { try { KChannel kChannel = KChannel.kChannels[(uint) user]; kChannel.Output(bytes, len); } catch (Exception e) { Log.Error(e); return len; } return len; }
protected override void Get(long id, IPEndPoint address) { if (this.idChannels.TryGetValue(id, out KChannel channel)) { return; } try { // 低32bit是localConn uint localConn = (uint)((ulong) id & uint.MaxValue); channel = new KChannel(id, localConn, this.socket, address, this); this.idChannels.Add(id, channel); this.localConnChannels.Add(channel.LocalConn, channel); } catch (Exception e) { Log.Error($"kservice get error: {id}\n{e}"); } }
public void ChangeAddress(long id, IPEndPoint address) { #if NET_THREAD this.ThreadSynchronizationContext.Post(() => { #endif KChannel kChannel = this.Get(id); if (kChannel == null) { return; } Log.Info($"channel change address: {id} {address}"); kChannel.RemoteAddress = address; #if NET_THREAD } ); #endif }
private void Recv() { if (this.socket == null) { return; } while (socket != null && this.socket.Available > 0) { int messageLength = this.socket.ReceiveFrom(this.cache, ref this.ipEndPoint); // 长度小于1,不是正常的消息 if (messageLength < 1) { continue; } // accept byte flag = this.cache[0]; // conn从100开始,如果为1,2,3则是特殊包 uint remoteConn = 0; uint localConn = 0; try { KChannel kChannel = null; switch (flag) { #if NOT_CLIENT case KcpProtocalType.SYN: // accept { // 长度!=5,不是SYN消息 if (messageLength < 9) { break; } string realAddress = null; remoteConn = BitConverter.ToUInt32(this.cache, 1); if (messageLength > 9) { realAddress = this.cache.ToStr(9, messageLength - 9); } remoteConn = BitConverter.ToUInt32(this.cache, 1); localConn = BitConverter.ToUInt32(this.cache, 5); this.waitConnectChannels.TryGetValue(remoteConn, out kChannel); if (kChannel == null) { localConn = CreateRandomLocalConn(this.random); // 已存在同样的localConn,则不处理,等待下次sync if (this.localConnChannels.ContainsKey(localConn)) { break; } long id = this.CreateAcceptChannelId(localConn); if (this.idChannels.ContainsKey(id)) { break; } kChannel = new KChannel(id, localConn, remoteConn, this.socket, this.CloneAddress(), this); this.idChannels.Add(kChannel.Id, kChannel); this.waitConnectChannels.Add(kChannel.RemoteConn, kChannel); // 连接上了或者超时后会删除 this.localConnChannels.Add(kChannel.LocalConn, kChannel); kChannel.RealAddress = realAddress; IPEndPoint realEndPoint = kChannel.RealAddress == null? kChannel.RemoteAddress : NetworkHelper.ToIPEndPoint(kChannel.RealAddress); this.OnAccept(kChannel.Id, realEndPoint); } if (kChannel.RemoteConn != remoteConn) { break; } // 地址跟上次的不一致则跳过 if (kChannel.RealAddress != realAddress) { Log.Error($"kchannel syn address diff: {kChannel.Id} {kChannel.RealAddress} {realAddress}"); break; } try { byte[] buffer = this.cache; buffer.WriteTo(0, KcpProtocalType.ACK); buffer.WriteTo(1, kChannel.LocalConn); buffer.WriteTo(5, kChannel.RemoteConn); Log.Info($"kservice syn: {kChannel.Id} {remoteConn} {localConn}"); this.socket.SendTo(buffer, 0, 9, SocketFlags.None, kChannel.RemoteAddress); } catch (Exception e) { Log.Error(e); kChannel.OnError(ErrorCode.ERR_SocketCantSend); } break; } #endif case KcpProtocalType.ACK: // connect返回 // 长度!=9,不是connect消息 if (messageLength != 9) { break; } remoteConn = BitConverter.ToUInt32(this.cache, 1); localConn = BitConverter.ToUInt32(this.cache, 5); kChannel = this.GetByLocalConn(localConn); if (kChannel != null) { Log.Info($"kservice ack: {kChannel.Id} {remoteConn} {localConn}"); kChannel.RemoteConn = remoteConn; kChannel.HandleConnnect(); } break; case KcpProtocalType.FIN: // 断开 // 长度!=13,不是DisConnect消息 if (messageLength != 13) { break; } remoteConn = BitConverter.ToUInt32(this.cache, 1); localConn = BitConverter.ToUInt32(this.cache, 5); int error = BitConverter.ToInt32(this.cache, 9); // 处理chanel kChannel = this.GetByLocalConn(localConn); if (kChannel == null) { break; } // 校验remoteConn,防止第三方攻击 if (kChannel.RemoteConn != remoteConn) { break; } Log.Info($"kservice recv fin: {kChannel.Id} {localConn} {remoteConn} {error}"); kChannel.OnError(ErrorCode.ERR_PeerDisconnect); break; case KcpProtocalType.MSG: // 断开 // 长度<9,不是Msg消息 if (messageLength < 9) { break; } // 处理chanel remoteConn = BitConverter.ToUInt32(this.cache, 1); localConn = BitConverter.ToUInt32(this.cache, 5); kChannel = this.GetByLocalConn(localConn); if (kChannel == null) { // 通知对方断开 this.Disconnect(localConn, remoteConn, ErrorCode.ERR_KcpNotFoundChannel, (IPEndPoint) this.ipEndPoint, 1); break; } // 校验remoteConn,防止第三方攻击 if (kChannel.RemoteConn != remoteConn) { break; } kChannel.HandleRecv(this.cache, 5, messageLength - 5); break; } } catch (Exception e) { Log.Error($"kservice error: {flag} {remoteConn} {localConn}\n{e}"); } } }