internal void SendPacket(int numBytes, IPEndPoint target, int numMessages, out bool connectionReset) { connectionReset = false; // simulate loss float loss = m_configuration.m_loss; if (loss > 0.0f) { if ((float)NetRandom.Instance.NextDouble() < loss) { LogVerbose("Sending packet " + numBytes + " bytes - SIMULATED LOST!"); return; // packet "lost" } } m_statistics.PacketSent(numBytes, numMessages); // simulate latency float m = m_configuration.m_minimumOneWayLatency; float r = m_configuration.m_randomOneWayLatency; if (m == 0.0f && r == 0.0f) { // no latency simulation // LogVerbose("Sending packet " + numBytes + " bytes"); bool wasSent = ActuallySendPacket(m_sendBuffer, numBytes, target, out connectionReset); // TODO: handle wasSent == false? return; } int num = 1; if (m_configuration.m_duplicates > 0.0f && NetRandom.Instance.NextSingle() < m_configuration.m_duplicates) { num++; } float delay = 0; for (int i = 0; i < num; i++) { delay = m_configuration.m_minimumOneWayLatency + (NetRandom.Instance.NextSingle() * m_configuration.m_randomOneWayLatency); // Enqueue delayed packet DelayedPacket p = new DelayedPacket(); p.Target = target; p.Data = new byte[numBytes]; Buffer.BlockCopy(m_sendBuffer, 0, p.Data, 0, numBytes); p.DelayedUntil = NetTime.Now + delay; m_delayedPackets.Add(p); } // LogVerbose("Sending packet " + numBytes + " bytes - delayed " + NetTime.ToReadable(delay)); }
public void NetworkReceivedPacket(ArraySegment <byte> data) { if (data.Array == null) { throw new ArgumentNullException("data"); } if (DebugSettings.Instance.EnableNetworkSimulation) { var reader = new PacketReader(data); reader.ReadUInt16(); // skip magic number (we don't want to error check it here, we'll let the error get caught in the normal way) var header = (MessageTypes)reader.ReadByte(); //Check if we should discard this packet to fake packet loss if (!IsReliable(header)) { var lossRoll = _rnd.NextDouble(); if (lossRoll < DebugSettings.Instance.PacketLoss) { return; } } var delay = _rnd.Next(DebugSettings.Instance.MinimumLatency, DebugSettings.Instance.MaximumLatency); var simulatedArrivalTime = DateTime.Now + TimeSpan.FromMilliseconds(delay); var dataCopy = new byte[data.Count]; Array.Copy(data.Array, data.Offset, dataCopy, 0, data.Count); var packet = new DelayedPacket { SimulatedReceiptTime = simulatedArrivalTime, Data = new ArraySegment <byte>(dataCopy) }; Interlocked.Increment(ref _delayedCount); if (IsOrdered(header)) { lock (_delayedOrderedPackets) _delayedOrderedPackets.Enqueue(packet); } else { lock (_delayedUnorderedPackets) _delayedUnorderedPackets.Add(packet); } } else { ProcessReceivedPacket(data); } }
internal void SendPacket(int numBytes, IPEndPoint target, int numMessages, out bool connectionReset) { connectionReset = false; // simulate loss float loss = m_configuration.m_loss; if (loss > 0.0f) { if ((float)NetRandom.Instance.NextDouble() < loss) { LogVerbose("Sending packet " + numBytes + " bytes - SIMULATED LOST!"); return; // packet "lost" } } m_statistics.PacketSent(numBytes, numMessages); // simulate latency float m = m_configuration.m_minimumOneWayLatency; float r = m_configuration.m_randomOneWayLatency; if (m == 0.0f && r == 0.0f) { // no latency simulation // LogVerbose("Sending packet " + numBytes + " bytes"); bool wasSent = ActuallySendPacket(m_sendBuffer, numBytes, target, out connectionReset); // TODO: handle wasSent == false? return; } int num = 1; if (m_configuration.m_duplicates > 0.0f && NetRandom.Instance.NextSingle() < m_configuration.m_duplicates) num++; float delay = 0; for (int i = 0; i < num; i++) { delay = m_configuration.m_minimumOneWayLatency + (NetRandom.Instance.NextSingle() * m_configuration.m_randomOneWayLatency); // Enqueue delayed packet DelayedPacket p = new DelayedPacket(); p.Target = target; p.Data = new byte[numBytes]; Buffer.BlockCopy(m_sendBuffer, 0, p.Data, 0, numBytes); p.DelayedUntil = NetTime.Now + delay; m_delayedPackets.Add(p); } // LogVerbose("Sending packet " + numBytes + " bytes - delayed " + NetTime.ToReadable(delay)); }
partial void DelayPacket(UdpEndPoint ep, byte[] data, int length) { DelayedPacket packet = new DelayedPacket(); packet.Data = delayedBuffers.Count > 0 ? delayedBuffers.Dequeue() : new byte[Config.MtuMax * 2]; packet.EndPoint = ep; packet.Length = length; packet.Time = GetCurrentTime() + (uint)random.Next(Config.SimulatedPingMin, Config.SimulatedPingMax); // copy entire buffer into packets data buffer Array.Copy(data, 0, packet.Data, 0, data.Length); // put on delay queue delayedPackets.Enqueue(packet); }
partial void DelayPacket(UdpEndPoint ep, byte[] data, int length) { uint pingMin = (uint) Config.SimulatedPingMin; uint pingMax = (uint) Config.SimulatedPingMax; uint delay = pingMin + (uint) ((pingMax - pingMin) * Config.NoiseFunction()); DelayedPacket packet = new DelayedPacket(); packet.Data = delayedBuffers.Count > 0 ? delayedBuffers.Dequeue() : new byte[Config.PacketSize * 2]; packet.EndPoint = ep; packet.Length = length; packet.Time = GetCurrentTime() + delay; // copy entire buffer into packets data buffer Array.Copy(data, 0, packet.Data, 0, data.Length); // put on delay queue delayedPackets.Enqueue(packet); }
partial void DelayPacket(UdpEndPoint ep, byte[] data, int length) { uint pingMin = (uint)Config.SimulatedPingMin; uint pingMax = (uint)Config.SimulatedPingMax; uint delay = pingMin + (uint)((pingMax - pingMin) * Config.NoiseFunction()); DelayedPacket packet = new DelayedPacket(); packet.Data = delayedBuffers.Count > 0 ? delayedBuffers.Dequeue() : new byte[Config.PacketSize * 2]; packet.EndPoint = ep; packet.Length = length; packet.Time = GetCurrentTime() + delay; // copy entire buffer into packets data buffer Array.Copy(data, 0, packet.Data, 0, data.Length); // put on delay queue delayedPackets.Enqueue(packet); }
partial void RecvDelayedPackets() { while (delayedPackets.Count > 0 && GetCurrentTime() >= delayedPackets.Peek().Time) { DelayedPacket packet = delayedPackets.Dequeue(); UdpStream stream = GetReadStream(); // copy data into streams buffer Array.Copy(packet.Data, 0, stream.Data, 0, packet.Data.Length); // clear packet data Array.Clear(packet.Data, 0, packet.Data.Length); // receive packet RecvNetworkPacket(packet.EndPoint, stream, packet.Length); // put packet data buffer back in pool delayedBuffers.Enqueue(packet.Data); } }
public int ExecuteSend(NetBase netBase, NetBuffer buffer, NetConnection connection, IPEndPoint remoteEP) { int len = buffer.LengthBytes; #if DEBUG if (connection != null) { NetConnectionConfiguration config = connection.Configuration; if (config.LossChance > 0.0f && NetRandom.Default.Chance(config.LossChance)) { //m_log.Debug("(simulating loss of sent packet)"); return(len); } if (config.LagDelayChance > 0.0f && NetRandom.Default.Chance(config.LagDelayChance)) { float delayAmount = config.LagDelayMinimum + (NetRandom.Default.NextFloat() * config.LagDelayVariance); DelayedPacket pk = new DelayedPacket(); pk.Data = new byte[len]; Array.Copy(buffer.Data, pk.Data, buffer.LengthBytes); pk.DelayAmount = delayAmount; pk.DelayedUntil = NetTime.Now + delayAmount; pk.RemoteEP = remoteEP; m_delayed.Add(pk); //m_log.Debug("(queueing packet for " + (int)(pk.DelayAmount * 1000.0f) + " ms)"); return(len); } } #endif try { int bytesSent = netBase.m_socket.SendTo(buffer.Data, 0, len, SocketFlags.None, remoteEP); m_log.Verbose(string.Format(CultureInfo.InvariantCulture, "Sent {0} bytes to {1}", bytesSent, remoteEP)); #if DEBUG if (connection != null) { NetConnectionConfiguration config = connection.Configuration; if (NetRandom.Default.Chance(config.DuplicatedPacketChance)) { m_log.Debug("(simulating send packet duplication)"); netBase.m_socket.SendTo(buffer.Data, 0, buffer.LengthBytes, SocketFlags.None, remoteEP); } } #endif return(bytesSent); } catch (SocketException sex) { if (sex.SocketErrorCode == SocketError.ConnectionReset || sex.SocketErrorCode == SocketError.ConnectionRefused || sex.SocketErrorCode == SocketError.ConnectionAborted) { m_log.Warning("Remote socket forcefully closed: " + sex.SocketErrorCode); if (connection != null) { connection.Disconnect("Socket forcefully closed: " + sex.SocketErrorCode); } return(0); } m_log.Warning("Execute SocketException: " + sex.SocketErrorCode); return(0); } }
public int ExecuteSend(NetBase netBase, NetBuffer buffer, NetConnection connection, IPEndPoint remoteEP) { int len = buffer.LengthBytes; #if DEBUG if (connection != null) { NetConnectionConfiguration config = connection.Configuration; if (config.LossChance > 0.0f && NetRandom.Default.Chance(config.LossChance)) { //m_log.Debug("(simulating loss of sent packet)"); return len; } if (config.LagDelayChance > 0.0f && NetRandom.Default.Chance(config.LagDelayChance)) { float delayAmount = config.LagDelayMinimum + (NetRandom.Default.NextFloat() * config.LagDelayVariance); DelayedPacket pk = new DelayedPacket(); pk.Data = new byte[len]; Array.Copy(buffer.Data, pk.Data, buffer.LengthBytes); pk.DelayAmount = delayAmount; pk.DelayedUntil = NetTime.Now + delayAmount; pk.RemoteEP = remoteEP; m_delayed.Add(pk); //m_log.Debug("(queueing packet for " + (int)(pk.DelayAmount * 1000.0f) + " ms)"); return len; } } #endif try { int bytesSent = netBase.m_socket.SendTo(buffer.Data, 0, len, SocketFlags.None, remoteEP); m_log.Verbose(string.Format(CultureInfo.InvariantCulture, "Sent {0} bytes to {1}", bytesSent, remoteEP)); #if DEBUG if (connection != null) { NetConnectionConfiguration config = connection.Configuration; if (NetRandom.Default.Chance(config.DuplicatedPacketChance)) { m_log.Debug("(simulating send packet duplication)"); netBase.m_socket.SendTo(buffer.Data, 0, buffer.LengthBytes, SocketFlags.None, remoteEP); } } #endif return bytesSent; } catch (SocketException sex) { if (sex.SocketErrorCode == SocketError.ConnectionReset || sex.SocketErrorCode == SocketError.ConnectionRefused || sex.SocketErrorCode == SocketError.ConnectionAborted) { m_log.Warning("Remote socket forcefully closed: " + sex.SocketErrorCode); if (connection != null) connection.Disconnect("Socket forcefully closed: " + sex.SocketErrorCode); return 0; } m_log.Warning("Execute SocketException: " + sex.SocketErrorCode); return 0; } }