/// <summary> /// Send a message to a peer still connected. /// </summary> /// <param name="Message">Message in String(UTF16 encode only).</param> /// <param name="PeerIP">IP:Port</param> /// <returns>If return False the sending is failed.</returns> public static void Send(string Message, string PeerIP) { Thread t = new Thread(new ParameterizedThreadStart(delegate { // convert the UTF16 to Byte[] byte[] Message_Byte = new byte[Message.Length * 2]; Message_Byte = ASCIIEncoding.Unicode.GetBytes(Message); PeersList.Peer peer = PeersList.GetPeerByIP(PeerIP); try { NetworkStream stream = peer.Client.GetStream(); stream.Write((byte[])Message_Byte, 0, ((byte[])Message_Byte).Length); } catch { // remove the peer PeersList.RemovePeer(PeerIP); Debug.WriteLine("A message hasn't been sent, probably the peer is offline or disconnected", "Error"); //MessageBox.Show("ERROR: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); // DEBUG } })); t.Name = "MessageSender"; t.IsBackground = true; t.Start(); }
/// <summary> /// Send a request of connection to all peers that are contained in the all XML-Lists if them aren't already connected with this client. /// Then deletes all XML-Lists. /// </summary> /// <param name="n">Max number of connections that will be opened. Set 0 to open all possible connections.</param> public static void ConnToPeers(int n = 0) { string[] lists = Directory.GetFiles((Global.TempDirectory + @"List\"), "List_*.xml", SearchOption.AllDirectories); foreach (string listPath in lists) { XmlDocument list = new XmlDocument(); // load the Xml-List while (true) { try { list.Load(listPath); break; } catch (IOException) { } catch (Exception ex) { Debug.WriteLine("Error to load a XML-List from " + listPath + " : " + ex.Message, "Error"); throw new IOException("Error to load a XML-List from " + listPath + " : " + ex.Message); } } XmlNodeList nodes = list.DocumentElement.GetElementsByTagName("Peers"); // get the single peers from the list int i = 0; foreach (XmlNode node in nodes) { if (i < n) { string IP = node.SelectSingleNode("IP").InnerText; // control if this peer is already connected with this client if (PeersList.GetPeerByIP(IP) == null) { string RequestConnectionMessage = Bouncer.RequestMessage(IP); MessageSender.SendConnectionRequest(RequestConnectionMessage, IP); } if (n != 0) { i++; } } else { break; } } // delete the list File.Delete(listPath); } }
/// <summary> /// Removes the peer from the tracker /// </summary> /// <param name="peer">The peer to remove</param> internal void Remove(Peer peer) { if (peer == null) { throw new ArgumentNullException(nameof(peer)); } Debug.WriteLine($"Removing: {peer.ClientAddress}"); Peers.Remove(peer.DictionaryKey); lock (PeersList) PeersList.Clear(); UpdateCounts(); }
/// <summary> /// Adds the peer to the tracker /// </summary> /// <param name="peer"></param> internal void Add(Peer peer) { if (peer == null) { throw new ArgumentNullException(nameof(peer)); } Debug.WriteLine(string.Format("Adding: {0}", peer.ClientAddress)); Peers.Add(peer.DictionaryKey, peer); lock (PeersList) PeersList.Clear(); UpdateCounts(); }
/// <summary> /// Send a message to a peer still connected ( USE THIS FOR SENDING MESSAGE WITH BINARY PARTS ) /// </summary> /// <param name="IMessage">Message in IMessage interface.</param> /// <param name="PeerIP">IP:Port</param> /// <returns>If return False the sending is failed.</returns> public static void Send(Messages.IMessage IMessage, string PeerIP) { byte[] Message_Byte = IMessage.MessageByte; PeersList.Peer peer = PeersList.GetPeerByIP(PeerIP); try { NetworkStream stream = peer.Client.GetStream(); stream.Write((byte[])Message_Byte, 0, ((byte[])Message_Byte).Length); } catch { // remove the peer PeersList.RemovePeer(PeerIP); Debug.WriteLine("A message hasn't been sent, probably the peer is offline or disconnected", "Error"); //MessageBox.Show("ERROR: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); // DEBUG } }
internal void ClearZombiePeers(DateTime cutoff) { bool removed = false; lock (PeersList) { foreach (Peer p in PeersList) { if (p.LastAnnounceTime > cutoff) { continue; } Tracker.RaisePeerTimedOut(new TimedOutEventArgs(p, this)); Peers.Remove(p.DictionaryKey); removed = true; } if (removed) { PeersList.Clear(); } } }
/// <summary> /// Send a Tcp connection request to a new peer. /// </summary> /// <param name="Message">The request message ( byte[] or string in UTF16 format ).</param> /// <param name="PeerIP">The IP address of the new peer.</param> public static void SendConnectionRequest(object Message, string PeerIP) { Thread t = new Thread(new ParameterizedThreadStart(delegate { if (Message.GetType().ToString() != "System.String" && Message.GetType().ToString() != "System.Byte[]") { throw new System.ArgumentException("The message format is invalid", "Message"); } // if necessary converts the UTF16 to Byte[] if (Message.GetType().ToString() == "System.String") { Message = ASCIIEncoding.Unicode.GetBytes((string)Message); } try { // connect to peer TcpClient client = new TcpClient(); client.Connect(PeerIP.Split(':')[0], int.Parse(PeerIP.Split(':')[1])); // get stream NetworkStream stream = client.GetStream(); // send the request stream.Write((byte[])Message, 0, ((byte[])Message).Length); // wait a reply System.Timers.Timer timer = new System.Timers.Timer(15000); timer.Elapsed += new ElapsedEventHandler(delegate { Thread.CurrentThread.Abort(); }); timer.Enabled = true; byte[] reply_byte = new byte[3072]; stream.Read(reply_byte, 0, reply_byte.Length); string reply = ASCIIEncoding.Unicode.GetString(reply_byte); string[] sub_reply = reply.Split('\n'); // if the peer have accepted the connection request... if (sub_reply[0].Substring(0, 4) == "Nova" && sub_reply[1].Substring(0, 10) == "CONNECT_OK") { Debug.WriteLine("Connection established with " + PeerIP, "Connection established"); // create a new PeersList.Peer() PeersList.Peer peer = new PeersList.Peer(); peer.IP = PeerIP; peer.Client = client; peer.Stream = stream; peer.ID = ""; // add the peer in the PeersList() PeersList.AddPeer(peer); } else { stream.Close(); client.Close(); } timer.Close(); } catch { Debug.WriteLine("A message hasn't been sent, probably the peer is offline or disconnected", "Error"); } })); t.Name = "MessageSender_Request_Connection_Sending"; t.IsBackground = true; t.Start(); }