private bool SendPacket(IPacket packet, bool guaranteed, int revision, EventHandler <IPacket> handler = null) { if (IsDisposed) { throw new ObjectDisposedException(GetType().Name); } if (packet == null) { throw new ArgumentNullException(nameof(packet)); } // wenn die Drohne nicht erreichbar ist if (!IsConnected) { if (Config.IgnoreGuaranteedWhenOffline) { guaranteed = false; } // alle Pakete (außer Ping) ignorieren wenn die Drohne offline ist if (packet.Type != PacketType.Ping && Config.IgnorePacketsWhenOffline) { return(false); } } lock (controlSocket) { bool alreadySent; lock (packetsToAcknowledge) { alreadySent = packetsToAcknowledge.ContainsKey(revision); if (guaranteed) { if (!stopwatch.IsRunning) { stopwatch.Start(); } packetsToAcknowledge[revision] = packet; packetSendTime[revision] = stopwatch.ElapsedMilliseconds; if (handler != null) { packetAcknowlegdeEvents[revision] = handler; } } } packetBuffer.ResetPosition(); // Paket-Header schreiben packetBuffer.Write((byte)'F'); packetBuffer.Write((byte)'L'); packetBuffer.Write((byte)'Y'); // Alle Daten werden nach dem Netzwerkstandard BIG-Endian übertragen packetBuffer.Write(revision); // wenn die Drohne eine Antwort schickt dann wird kein Ack-Paket angefordert, sonst kann es passieren, dass das Ack-Paket die eigentliche Antwort verdrängt packetBuffer.Write(guaranteed && !packet.Type.DoesClusterAnswer()); packetBuffer.Write((byte)packet.Type); // Paket Inhalt schreiben packet.Write(packetBuffer); controlSocket.BeginSend(packetStream.GetBuffer(), (int)packetBuffer.Position, SendPacket, null); if (Config.VerbosePacketSending && (packet.Type != PacketType.Ping || Config.LogPingPacket)) { Log.Verbose("[{0}] Packet: [{1}] {2}, size: {3} bytes {4} {5}", Address.ToString(), revision, packet.Type, packetBuffer.Position, guaranteed ? "(guaranteed)" : "", alreadySent ? "(resend)" : ""); } } return(true); }