static public void User(string format, params object[] args) { if (UdpMath.IsSet(enabled, INFO)) { Write(USER, String.Concat(Time(), ThreadName(), " | user | ", String.Format(format, args))); } }
static public void Trace(string format, params object[] args) { if (UdpMath.IsSet(UdpLog.enabled, UdpLog.TRACE)) { Write(TRACE, String.Concat(Time(), ThreadName(), " | trace | ", String.Format(format, args))); } }
static public void Info(string format, params object[] args) { if (UdpMath.IsSet(enabled, INFO)) { Write(INFO, String.Concat(Time(), ThreadName(), " | info | ", String.Format(format, args))); } }
static internal void Info(string format, params object[] args) { if (UdpMath.IsSet(UdpLog.enabled, UdpLog.INFO)) { Write(String.Concat(Time(), ThreadName(), " | info | ", String.Format(format, args))); } }
public UdpStream Acquire() { UdpStream stream = null; lock (pool) { if (pool.Count > 0) { stream = pool.Pop(); } } if (stream == null) { stream = new UdpStream(new byte[socket.Config.PacketSize * 2]); stream.Pool = this; } UdpAssert.Assert(stream.IsPooled); stream.IsPooled = false; stream.Position = 0; stream.Size = (socket.Config.PacketSize - UdpMath.BytesRequired(UdpSocket.HeaderBitSize)) << 3; return(stream); }
static public void Debug(string format, params object[] args) { #if DEBUG if (UdpMath.IsSet(enabled, DEBUG)) { Write(DEBUG, String.Concat(Time(), ThreadName(), " | debug | ", String.Format(format, args))); } #endif }
static internal void Debug(string format, params object[] args) { #if DEBUG if (UdpMath.IsSet(UdpLog.enabled, UdpLog.DEBUG)) { Write(String.Concat(Time(), ThreadName(), " | debug | ", String.Format(format, args), "\r\n", Environment.StackTrace)); } #endif }
static public void Warn(string format, params object[] args) { if (UdpMath.IsSet(enabled, WARN)) { #if DEBUG Write(WARN, String.Concat(Time(), ThreadName(), " | warn | ", String.Format(format, args), "\r\n", Environment.StackTrace)); #else Write(WARN, String.Concat(Time(), ThreadName(), " | warn | ", String.Format(format, args))); #endif } }
void AckHandles(UdpHeader header, bool updateRtt) { while (!sendWindow.Empty) { UdpHandle handle = sendWindow.Peek(); int seqDistance = UdpMath.SeqDistance(handle.ObjSequence, header.AckSequence, UdpHeader.SEQ_PADD); if (seqDistance > 0) { break; } if (handle.IsObject) { if (seqDistance <= -UdpSocket.AckRedundancy) { // track stats stats.PacketLost(); socket.Statistics.PacketLost(); // handle lost ObjectLost(handle.Object); } else { if ((header.AckHistory & (1UL << -seqDistance)) != 0UL) { // track stats stats.PacketDelivered(); socket.Statistics.PacketDelivered(); // handle delivered objects ObjectDelivered(handle.Object); } else { // track stats stats.PacketLost(); socket.Statistics.PacketLost(); // handle ObjectLost(handle.Object); } } } if (seqDistance == 0 && header.AckTime > 0) { UpdatePing(recvTime, handle.SendTime, header.AckTime); } sendWindow.Dequeue(); } }
static internal void Warn(string format, params object[] args) { if (UdpMath.IsSet(UdpLog.enabled, UdpLog.WARN)) { #if DEBUG Write(String.Concat(Time(), ThreadName(), " | warn | ", String.Format(format, args), "\r\n", Environment.StackTrace)); #else write(String.Concat(timePadded(), threadName(), " | warn | ", String.Format(format, args))); #endif } }
void UpdatePing(uint recvTime, uint sendTime, uint ackTime) { uint aliased = recvTime - sendTime; aliasedRtt = (aliasedRtt * 0.9f) + ((float)aliased / 1000f * 0.1f); if (UdpSocket.CalculateNetworkPing) { uint network = aliased - UdpMath.Clamp(ackTime, 0, aliased); networkRtt = (networkRtt * 0.9f) + ((float)network / 1000f * 0.1f); } }
internal void OnEventConnectionOption(UdpEvent ev) { switch (ev.Option) { case UdpConnectionOption.AlwaysSendMtu: alwaysSendMtu = ev.OptionIntValue == 1; break; case UdpConnectionOption.MtuSize: mtu = UdpMath.Clamp(ev.OptionIntValue, socket.Config.MtuMin, socket.Config.MtuMax); break; } }
bool SendStream(UdpStream stream, UdpHandle handle, bool expandToMtu) { int bytesToSend = UdpMath.BytesRequired(stream.Ptr); if (bytesToSend < mtu && expandToMtu) { bytesToSend = mtu; } sendTime = handle.SendTime; sendSequence = handle.ObjSequence; sendWindow.Enqueue(handle); recvSinceLastSend = 0; return(socket.Send(endpoint, stream.Data, bytesToSend)); }
bool ParseHeader(ref UdpBitStream buffer) { UdpHeader header = new UdpHeader(); header.Unpack(new UdpBitStream(buffer.Data, buffer.Length, 0), socket); // Assign bit size if (socket.Config.WritePacketBitSize) { buffer.Length = header.BitSize; } int seqDistance = UdpMath.SeqDistance(header.ObjSequence, recvSequence, UdpHeader.SEQ_PADD); // we have to be within window size if (seqDistance > socket.Config.PacketWindow || seqDistance < -socket.Config.PacketWindow) { ConnectionError(UdpConnectionError.SequenceOutOfBounds); return(false); } // this is an old packet if (seqDistance <= 0) { return(false); } // update receive history if (seqDistance >= socket.Config.AckRedundancy) { recvHistory = 1UL; } else { recvHistory = (recvHistory << seqDistance) | 1UL; } // update our receive stats recvSequence = header.ObjSequence; recvSinceLastSend += 1; // ack sent objects AckHandles(header, true); return(true); }
UdpHeader MakeHeader(bool isObject) { UdpHeader header = new UdpHeader(); header.IsObject = isObject; header.AckHistory = recvHistory; header.AckSequence = recvSequence; header.ObjSequence = UdpMath.SeqNext(sendSequence, UdpHeader.SEQ_MASK); header.Now = socket.GetCurrentTime(); if (recvTime > 0) { header.AckTime = (ushort)UdpMath.Clamp(header.Now - recvTime, 0, socket.Config.MaxPing); } return(header); }
bool ParseHeader(UdpStream stream) { // we should always start at ptr 0 UdpAssert.Assert(stream.Ptr == 0); UdpHeader header = new UdpHeader(); header.Unpack(stream, socket); // after unpacking the header, the pointer should be at the header size UdpAssert.Assert(stream.Ptr == UdpSocket.HeaderBitSize); int seqDistance = UdpMath.SeqDistance(header.ObjSequence, recvSequence, UdpHeader.SEQ_PADD); // we have to be within window size if (seqDistance > socket.Config.PacketWindow || seqDistance < -socket.Config.PacketWindow) { ConnectionError(UdpConnectionError.SequenceOutOfBounds); return(false); } // this is an old packet if (seqDistance <= 0) { return(false); } // update receive history if (seqDistance >= UdpSocket.AckRedundancy) { recvHistory = 1UL; } else { recvHistory = (recvHistory << seqDistance) | 1UL; } // update our receive stats recvSequence = header.ObjSequence; recvSinceLastSend += 1; // ack sent objects AckHandles(header, true); return(true); }
void SendRefusedCommand(UdpEndPoint endpoint) { UdpStream stream = GetWriteStream(Config.PacketSize << 3, HeaderBitSize); stream.WriteByte((byte)UdpCommandType.Refused, 8); UdpHeader header = new UdpHeader(); header.IsObject = false; header.AckHistory = 0; header.AckSequence = 1; header.ObjSequence = 1; header.Now = 0; header.Pack(stream, this); if (Send(endpoint, stream.Data, UdpMath.BytesRequired(stream.Ptr)) == false) { // do something here? } }
public UdpReliableBuffer(uint windowSize) { if (windowSize < (1 << 2)) { throw new ArgumentException("Must be >= (1 << 2)", "windowSize"); } if (windowSize > (1 << 14)) { throw new ArgumentException("Must be <= (1 << 14)", "windowSize"); } if (UdpMath.IsPowerOfTwo(windowSize) == false) { throw new ArgumentException("Must be a power of two", "windowSize"); } SequenceBits = UdpMath.HighBit(windowSize) + 2; recv = new UdpReliableRecvQueue <T>(SequenceBits); send = new UdpReliableSendQueue <T>(SequenceBits); }
void SendRefusedCommand(UdpEndPoint endpoint) { UdpBitStream stream = new UdpBitStream(GetWriteBuffer(), Config.DefaultMtu, UdpHeader.GetSize(this)); stream.WriteByte((byte)UdpCommandType.Refused, 8); UdpHeader header = new UdpHeader(); header.IsObject = false; header.AckHistory = 0; header.AckSequence = 1; header.ObjSequence = 1; header.Now = 0; header.Pack(new UdpBitStream(stream.Data, Config.DefaultMtu, 0), this); if (Send(endpoint, stream.Data, UdpMath.BytesRequired(stream.Ptr)) == false) { // do something here? } }
void AckHandles(UdpHeader header, bool updateRtt) { while (!sendWindow.Empty) { UdpHandle handle = sendWindow.Peek(); int seqDistance = UdpMath.SeqDistance(handle.ObjSequence, header.AckSequence, UdpHeader.SEQ_PADD); if (seqDistance > 0) { break; } if (handle.IsObject) { if (seqDistance <= -socket.Config.AckRedundancy) { ObjectLost(handle.Object); } if ((header.AckHistory & (1UL << -seqDistance)) != 0UL) { ObjectDelivered(handle.Object); } else { ObjectLost(handle.Object); } } if (seqDistance == 0 && header.AckTime > 0) { UpdatePing(recvTime, handle.SendTime, header.AckTime); } sendWindow.Dequeue(); } }