protected override bool QueueChunkEx(ChunkFlags flags, byte[] data, int dataSize, int sequence) { if (ResendChunkConstruct.DataSize + dataSize + NetworkHelper.MaxChunkHeaderSize > ResendChunkConstruct.Data.Length || ResendChunkConstruct.NumChunks >= NetworkHelper.MaxPacketChunks) { Flush(); } var header = new ChunkHeader { Flags = flags, Size = dataSize, Sequence = sequence }; var dataOffset = ResendChunkConstruct.DataSize; dataOffset = header.Pack(ResendChunkConstruct.Data, dataOffset); Buffer.BlockCopy(data, 0, ResendChunkConstruct.Data, dataOffset, dataSize); ResendChunkConstruct.NumChunks++; ResendChunkConstruct.DataSize = dataOffset + dataSize; if (flags.HasFlag(ChunkFlags.Vital) && !flags.HasFlag(ChunkFlags.Resend)) { SizeOfChunksForResends += 32 + dataSize; if (SizeOfChunksForResends >= NetworkHelper.ConnectionBufferSize) { Disconnect("too weak connection (out of buffer)"); return(false); } var resend = new ChunkResend { Sequence = sequence, Flags = flags, DataSize = dataSize, Data = new byte[dataSize], FirstSendTime = Time.Get(), LastSendTime = Time.Get() }; Buffer.BlockCopy(data, 0, resend.Data, 0, dataSize); ChunksForResends.Add(resend); } return(true); }
protected override void AckChunks(int ack) { while (true) { if (ChunksForResends.Count == 0) { return; } if (NetworkHelper.IsSequenceInBackroom(ChunksForResends[0].Sequence, ack)) { SizeOfChunksForResends -= 32 + ChunksForResends[0].DataSize; ChunksForResends.RemoveAt(0); // TODO make Unidirectional list } else { return; } } }
protected override void Reset() { Sequence = 0; Ack = 0; PeerAck = 0; RemoteClosed = false; State = ConnectionState.Offline; LastSendTime = 0; LastReceiveTime = 0; ConnectedAt = 0; Token = TokenHelper.TokenNone; PeerToken = TokenHelper.TokenNone; EndPoint = null; ChunksForResends.Clear(); SizeOfChunksForResends = 0; Error = string.Empty; ResetChunkConstruct(); }