public void HandleRecv(byte[] date, int offset, int length) { if (this.IsDisposed) { return; } this.isConnected = true; Kcp.KcpInput(this.kcp, date, offset, length); this.GetService().AddToUpdateNextTime(0, this.Id); while (true) { if (this.IsDisposed) { return; } int n = Kcp.KcpPeeksize(this.kcp); if (n < 0) { return; } if (n == 0) { this.OnError((int)SocketError.NetworkReset); return; } byte[] buffer = this.memoryStream.GetBuffer(); this.memoryStream.SetLength(n); this.memoryStream.Seek(0, SeekOrigin.Begin); int count = Kcp.KcpRecv(this.kcp, buffer, ushort.MaxValue); if (n != count) { return; } if (count <= 0) { return; } this.lastRecvTime = this.GetService().TimeNow; this.OnRead(this.memoryStream); } }
public void Update() { if (this.IsDisposed) { return; } uint timeNow = this.Service.TimeNow; // 如果还没连接上,发送连接请求 if (!this.IsConnected) { // 20秒没连接上则报错 if (timeNow - this.CreateTime > 10 * 1000) { Log.Error($"kChannel connect timeout: {this.Id} {this.RemoteConn} {timeNow} {this.CreateTime} {this.ChannelType} {this.RemoteAddress}"); this.OnError(ErrorCode.ERR_KcpConnectTimeout); return; } switch (ChannelType) { case ChannelType.Connect: this.Connect(); break; } return; } try { Kcp.KcpUpdate(this.kcp, timeNow); } catch (Exception e) { Log.Error(e); this.OnError(ErrorCode.ERR_SocketError); return; } if (this.kcp != IntPtr.Zero) { uint nextUpdateTime = Kcp.KcpCheck(this.kcp, timeNow); this.Service.AddToUpdateNextTime(nextUpdateTime, this.Id); } }
// accept public KChannel(long id, uint localConn, uint remoteConn, Socket socket, IPEndPoint remoteEndPoint, KService kService) { this.Id = id; this.ChannelType = ChannelType.Accept; Log.Info($"channel create: {this.Id} {localConn} {remoteConn} {remoteEndPoint} {this.ChannelType}"); this.Service = kService; this.LocalConn = localConn; this.RemoteConn = remoteConn; this.RemoteAddress = remoteEndPoint; this.socket = socket; this.kcp = Kcp.KcpCreate(this.RemoteConn, IntPtr.Zero); this.InitKcp(); this.lastRecvTime = kService.TimeNow; this.CreateTime = kService.TimeNow; }
// accept public KChannel(uint localConn, uint remoteConn, Socket socket, IPEndPoint remoteEndPoint, KService kService) : base(kService, ChannelType.Accept) { this.memoryStream = this.GetService().MemoryStreamManager.GetStream("message", ushort.MaxValue); this.LocalConn = localConn; this.RemoteConn = remoteConn; this.remoteEndPoint = remoteEndPoint; this.socket = socket; this.kcp = Kcp.KcpCreate(this.RemoteConn, new IntPtr(this.LocalConn)); SetOutput(); Kcp.KcpNodelay(this.kcp, 1, 10, 1, 1); Kcp.KcpWndsize(this.kcp, 256, 256); Kcp.KcpSetmtu(this.kcp, 470); this.lastRecvTime = kService.TimeNow; this.createTime = kService.TimeNow; this.Accept(); }
private void InitKcp() { switch (this.Service.ServiceType) { case ServiceType.Inner: Kcp.KcpNodelay(kcp, 1, 10, 2, 1); Kcp.KcpWndsize(kcp, 1024 * 100, 1024 * 100); Kcp.KcpSetmtu(kcp, 1400); // 默认1400 Kcp.KcpSetminrto(kcp, 10); break; case ServiceType.Outer: Kcp.KcpNodelay(kcp, 1, 10, 2, 1); Kcp.KcpWndsize(kcp, 128, 128); Kcp.KcpSetmtu(kcp, 470); Kcp.KcpSetminrto(kcp, 10); break; } }
private void KcpSend(KcpWaitPacket kcpWaitPacket) { if (this.IsDisposed) { return; } MemoryStream memoryStream = kcpWaitPacket.MemoryStream; if (this.Service.ServiceType == ServiceType.Inner) { memoryStream.GetBuffer().WriteTo(0, kcpWaitPacket.ActorId); } int count = (int)(memoryStream.Length - memoryStream.Position); Kcp.KcpSend(this.kcp, memoryStream.GetBuffer(), (int)memoryStream.Position, count); this.Service.AddToUpdateNextTime(0, this.Id); }
private void KcpSend(KcpWaitPacket kcpWaitPacket) { if (this.IsDisposed) { return; } MemoryStream memoryStream = kcpWaitPacket.MemoryStream; int count = (int)(memoryStream.Length - memoryStream.Position); if (this.Service.ServiceType == ServiceType.Inner) { memoryStream.GetBuffer().WriteTo(0, kcpWaitPacket.ActorId); } // 超出maxPacketSize需要分片 if (count <= maxPacketSize) { Kcp.KcpSend(this.kcp, memoryStream.GetBuffer(), (int)memoryStream.Position, count); } else { // 先发分片信息 this.sendCache.WriteTo(0, 0); this.sendCache.WriteTo(4, count); Kcp.KcpSend(this.kcp, this.sendCache, 0, 8); // 分片发送 int alreadySendCount = 0; while (alreadySendCount < count) { int leftCount = count - alreadySendCount; int sendCount = leftCount < maxPacketSize? leftCount: maxPacketSize; Kcp.KcpSend(this.kcp, memoryStream.GetBuffer(), (int)memoryStream.Position + alreadySendCount, sendCount); alreadySendCount += sendCount; } } this.Service.AddToUpdateNextTime(0, this.Id); }
public void Send(long actorId, MemoryStream stream) { if (this.kcp != IntPtr.Zero) { // 检查等待发送的消息,如果超出最大等待大小,应该断开连接 int n = Kcp.KcpWaitsnd(this.kcp); int maxWaitSize = 0; switch (this.Service.ServiceType) { case ServiceType.Inner: maxWaitSize = Kcp.InnerMaxWaitSize; break; case ServiceType.Outer: maxWaitSize = Kcp.OuterMaxWaitSize; break; default: throw new ArgumentOutOfRangeException(); } if (n > maxWaitSize) { Log.Error($"kcp wait snd too large: {n}: {this.Id} {this.RemoteConn}"); this.OnError(ErrorCode.ERR_KcpWaitSendSizeTooLarge); return; } } KcpWaitPacket kcpWaitPacket = new KcpWaitPacket() { ActorId = actorId, MemoryStream = stream }; if (!this.IsConnected) { this.sendBuffer.Enqueue(kcpWaitPacket); return; } this.KcpSend(kcpWaitPacket); }
private void InitKcp() { KcpPtrChannels.Add(this.kcp, this); switch (this.Service.ServiceType) { case ServiceType.Inner: Kcp.KcpNodelay(kcp, 1, 10, 2, 1); Kcp.KcpWndsize(kcp, ushort.MaxValue, ushort.MaxValue); Kcp.KcpSetmtu(kcp, 1400); // 默认1400 Kcp.KcpSetminrto(kcp, 30); break; case ServiceType.Outer: Kcp.KcpNodelay(kcp, 1, 10, 2, 1); Kcp.KcpWndsize(kcp, 256, 256); Kcp.KcpSetmtu(kcp, 470); Kcp.KcpSetminrto(kcp, 30); break; } }
public void HandleConnnect(uint remoteConn) { if (this.isConnected) { return; } this.RemoteConn = remoteConn; this.kcp = Kcp.KcpCreate(this.RemoteConn, new IntPtr(this.LocalConn)); SetOutput(); Kcp.KcpNodelay(this.kcp, 1, 10, 1, 1); Kcp.KcpWndsize(this.kcp, 256, 256); Kcp.KcpSetmtu(this.kcp, 470); this.isConnected = true; this.lastRecvTime = this.GetService().TimeNow; HandleSend(); }
public override void Dispose() { if (this.IsDisposed) { return; } uint localConn = this.LocalConn; uint remoteConn = this.RemoteConn; Log.Info($"channel dispose: {this.Id} {localConn} {remoteConn}"); kChannels.Remove(localConn); idLocalRemoteConn.Remove(this.Id); // idLocalRemoteConn.TryRemove(this.Id, out ulong _); long id = this.Id; this.Id = 0; this.Service.Remove(id); try { //this.Service.Disconnect(localConn, remoteConn, this.Error, this.RemoteAddress, 3); } catch (Exception e) { Log.Error(e); } if (this.kcp != IntPtr.Zero) { Kcp.KcpRelease(this.kcp); this.kcp = IntPtr.Zero; } this.socket = null; }
public void HandleRecv(byte[] date, int offset, int length) { if (this.IsDisposed) { return; } this.IsConnected = true; Kcp.KcpInput(this.kcp, date, offset, length); this.Service.AddToUpdateNextTime(0, this.Id); while (true) { if (this.IsDisposed) { break; } int n = Kcp.KcpPeeksize(this.kcp); if (n < 0) { break; } if (n == 0) { this.OnError((int)SocketError.NetworkReset); return; } if (this.needReadSplitCount > 0) // 说明消息分片了 { byte[] buffer = readMemory.GetBuffer(); int count = Kcp.KcpRecv(this.kcp, buffer, (int)this.readMemory.Length - this.needReadSplitCount, n); this.needReadSplitCount -= count; if (n != count) { Log.Error($"kchannel read error1: {this.LocalConn} {this.RemoteConn}"); this.OnError(ErrorCore.ERR_KcpReadNotSame); return; } if (this.needReadSplitCount < 0) { Log.Error($"kchannel read error2: {this.LocalConn} {this.RemoteConn}"); this.OnError(ErrorCore.ERR_KcpSplitError); return; } // 没有读完 if (this.needReadSplitCount != 0) { continue; } } else { this.readMemory = this.ms; this.readMemory.SetLength(n); this.readMemory.Seek(0, SeekOrigin.Begin); byte[] buffer = readMemory.GetBuffer(); int count = Kcp.KcpRecv(this.kcp, buffer, 0, n); if (n != count) { break; } // 判断是不是分片 if (n == 8) { int headInt = BitConverter.ToInt32(this.readMemory.GetBuffer(), 0); if (headInt == 0) { this.needReadSplitCount = BitConverter.ToInt32(readMemory.GetBuffer(), 4); if (this.needReadSplitCount <= maxPacketSize) { Log.Error($"kchannel read error3: {this.needReadSplitCount} {this.LocalConn} {this.RemoteConn}"); this.OnError(ErrorCore.ERR_KcpSplitCountError); return; } this.readMemory = new MemoryStream(this.needReadSplitCount); this.readMemory.SetLength(this.needReadSplitCount); this.readMemory.Seek(0, SeekOrigin.Begin); continue; } } } switch (this.Service.ServiceType) { case ServiceType.Inner: this.readMemory.Seek(Packet.ActorIdLength + Packet.OpcodeLength, SeekOrigin.Begin); break; case ServiceType.Outer: this.readMemory.Seek(Packet.OpcodeLength, SeekOrigin.Begin); break; } this.lastRecvTime = this.Service.TimeNow; MemoryStream mem = this.readMemory; this.readMemory = null; this.OnRead(mem); } }
static KService() { //Kcp.KcpSetLog(KcpLog); Kcp.KcpSetoutput(KcpOutput); }
public void Update() { if (this.IsDisposed) { return; } uint timeNow = this.GetService().TimeNow; // 如果还没连接上,发送连接请求 if (!this.isConnected) { // 10秒没连接上则报错 if (timeNow - this.createTime > 10 * 1000) { this.OnError(ErrorCode.ERR_KcpCantConnect); return; } if (timeNow - this.lastRecvTime < 500) { return; } switch (ChannelType) { case ChannelType.Accept: this.Accept(); break; case ChannelType.Connect: this.Connect(); break; } return; } // 超时断开连接 //if (timeNow - this.lastRecvTime > 40 * 1000) //{ // this.OnError(ErrorCode.ERR_KcpChannelTimeout); // return; //} try { Kcp.KcpUpdate(this.kcp, timeNow); } catch (Exception e) { Log.Error(e); this.OnError(ErrorCode.ERR_SocketError); return; } if (this.kcp != IntPtr.Zero) { uint nextUpdateTime = Kcp.KcpCheck(this.kcp, timeNow); this.GetService().AddToUpdateNextTime(nextUpdateTime, this.Id); } }