/// <summary> /// Send a packet to a target IP address. /// </summary> /// <param name="sender">Default object parameter for event receiving methods. Unused here.</param> /// <param name="args">PacketTransmissionEventArgs object containing the byte array to be send and the destination IP address.</param> public void SendPacket(object sender, PacketTransmissionEventArgs args) { ControlledPacket ctrlPacket = new ControlledPacket(); ctrlPacket.Recipient = args.Destination; ctrlPacket.Data = args.PacketContent; _messageSendingControlList.Add(ctrlPacket); }
/// <summary> /// Attempt to send the controlled packet. Return true if successful. /// </summary> /// <param name="ctrlPacket">Packet to be sent.</param> protected bool SendControlledPacket(ControlledPacket ctrlPacket) { try { _client.Send(ctrlPacket.Data, ctrlPacket.Data.Length, ctrlPacket.Recipient); // Send the packet. } catch (SocketException ex) { #if DEBUG throw; #else System.Diagnostics.Debug.WriteLine("### An error happened when trying to send ControlledPacket:"); System.Diagnostics.Debug.WriteLine("### " + ex.Message); System.Diagnostics.Debug.WriteLine("### " + ex.ToString()); return(false); #endif } return(true); }
/// <summary> /// This is a threaded method that keeps looping while _online is true. /// It will receive UDP messages on the UdpClient's port number and forward them to the OnPacketReceived event. /// </summary> public void ReceivePacket() // Threaded looping method. { while (_online) { try { IPEndPoint remoteSender = new IPEndPoint(IPAddress.Any, 0); byte[] receivedBytes = _client.Receive(ref remoteSender); if (receivedBytes != null && receivedBytes.Length != 0) { if (receivedBytes.Length == ByteHelper.HashByteLength + 2 && receivedBytes[0] == 0xCE && receivedBytes[receivedBytes.Length - 1] == 0xCE) { if (_messageSendingControlList.Count != 0) { // The received message is a ACK message. string hash = OpenAck(receivedBytes); ControlledPacket packet = _messageSendingControlList.Find(x => x.Hash == hash); if (packet != null) { _messageSendingControlList.Remove(packet); } } } else if (receivedBytes.Length == 1 && receivedBytes[0] == 0xEC) { // Fire an OnEtherConnectionReply event. OnEtherConnectionReply(null); } else { // Send back an ACK packet. string hash = ByteHelper.GetHashString(receivedBytes); byte[] ackBytes = CreateAck(hash); _client.Send(ackBytes, ackBytes.Length, remoteSender); // Check if the message is a duplicate. if (!_messageReceivingControlList.Any(x => x == hash)) { // Add the message's hash to a list so we don't react on the same message twice. _messageReceivingControlList.Add(hash); if (_messageReceivingControlList.Count > 5) // Only keep the latest 5 messages. { _messageReceivingControlList.RemoveAt(0); } // Fire an OnPacketReceived event. PacketReceivedEventArgs args = new PacketReceivedEventArgs(); args.Sender = remoteSender; args.Data = receivedBytes; OnPacketReceived(args); } } } } catch (SocketException ex) { if (ex.SocketErrorCode != SocketError.TimedOut) { System.Diagnostics.Debug.WriteLine("### " + _threadPacketListener.Name + " has crashed:"); System.Diagnostics.Debug.WriteLine("### " + ex.Message); System.Diagnostics.Debug.WriteLine("### " + ex.ToString()); break; } else { continue; } } } }