/// <summary> /// Finds the peers that have the file and add them in the list of peers. /// </summary> public void FindPeers() { // search the file in net Utilities.FileSearcher.SearchFile(this.Name); // get the file from the list of found files Lists.FilesFoundList.File file = Lists.FilesFoundList.GetFile(this.Name, this.SHA1); if (file != null) { for (int i = 0; i < file.ListPeers.Count; i++) { try { Objects.Peer peer = Lists.PeersList.GetPeerByIP(file.ListPeers[i].IP); if (peer != null) { AddPeer(peer); } } catch { } } } }
/// <summary> /// Send a new FPR to the peer for download a file pack of a not-downloading file part. /// </summary> /// <param name="download">The download object.</param> /// <param name="Peer">The IP address of peer to send the FPR message.</param> /// <returns>Return true if the message has been sended.</returns> private static bool StartDownloadNextFilePart(Objects.Download download, Objects.Peer Peer) { // the index of the not-downloaded file parts int[] index = new int[download.RemainingFileParts]; int n = 0; // get the not-downloaded file parts for (int i = 0; i < download.ListFileParts.Length; i++) { if (download.ListFileParts[i] == 128 || (download.ListFileParts[i] > 0 && i == (download.ListFileParts.Length - 1))) { index[n] = i; n++; } } // select a random not-downloaded file part to download Random random = new Random(); if (n > 0) { while (true) { int a = 0; if (download.RemainingFileParts != 0) { a = random.Next(n); if (download.ListFileParts[index[a]] != 0) { // start to download the file part string[] Params = new string[3]; Params[0] = download.Name; Params[1] = download.SHA1; Params[2] = (index[a] * 16384).ToString(); Messages.IMessage FprMess = Messages.MessagesFactory.Instance.CreateMessage(Messages.Commands.FPR, Params); Peer.Send(FprMess); return(true); } } else { return(false); } } } else { return(false); } }
/// <summary> /// Get the info of a single peer. /// </summary> /// <param name="PeerID">The ID of peer.</param> public static void GetSinglePeerInfoByID(string PeerID) { IMessage iPImessage = MessagesFactory.Instance.CreateMessage(Commands.PI, ""); Objects.Peer peer = Lists.PeersList.GetPeerByID(PeerID); if (peer != null) { peer.Send(iPImessage); } }
/// <summary> /// Generic message. /// </summary> /// <param name="CommandName">The command name.</param> /// <param name="MessageID">The message ID.</param> /// <param name="TTL">The time to live.</param> /// <param name="Encryption">Indicates if the message is encrypted or not.</param> /// <param name="SenderPeer">The sender peer.</param> public AbstractMessage(Commands CommandName, String MessageID, int TTL, bool Encryption, Objects.Peer SenderPeer = null) { this.m_cmdCommandName = CommandName; this.m_nTTL = TTL; this.m_bEncrypted = Encryption; this.m_senderPeer = SenderPeer; if (MessageID == String.Empty) { this.m_ID = this.GenerateID(); } else { this.m_ID = MessageID; } }
/// <summary> /// Control if there is the minimum number of uploader peers else get other uploader peers. /// </summary> /// <param name="download">The download object.</param> /// <returns>Return true if there is the minimum number of the uploader peers else return false.</returns> private static bool CheckMinNumberOfUploaderPeers(Objects.Download download) { if (download.ListUploaderPeers.Count < NumPeersForEachDownloads) { System.Random random = new Random(); while (download.ListUploaderPeers.Count < NumPeersForEachDownloads) { // control if there are peers that have this file if (download.ListPeers.Count == 0) { download.FindPeers(); } if (download.ListPeers.Count > download.ListUploaderPeers.Count) { // get a casual peer Objects.Peer peer = download.ListPeers[random.Next(download.ListPeers.Count)]; // control if the peer is already an uploader if (download.SearchUploaderPeer(peer.Key) == null) { // add the peer in the list of the uploader peers of the download download.AddUploaderPeer(peer); // send a FPR message to the new uploader peer if (StartDownloadNextFilePart(download, peer) == false) { DownloadFirstNotDownloadedFilePack(download, peer); } } } else { return(false); } } return(true); } else { return(true); } }
/// <summary> /// Adds a peer in the list of uploader peers of this download. /// </summary> /// <param name="peer"></param> public void AddUploaderPeer(Objects.Peer peer) { if (this.ListUploaderPeers.Count > 0) { int n = 0; int max = ListPeers.Count - 1; int min = 0; while (max >= min) { n = (max + min) / 2; if (peer.Key > this.ListUploaderPeers[n].Key) { min = n + 1; } else if (peer.Key < this.ListUploaderPeers[n].Key) { max = n - 1; } else { return; } } if (peer.Key < this.ListUploaderPeers[n].Key) { n--; } this.ListUploaderPeers.Add(this.ListUploaderPeers[this.ListUploaderPeers.Count - 1]); for (int i = this.ListUploaderPeers.Count - 1; i > n + 1; i--) { this.ListUploaderPeers[i] = this.ListUploaderPeers[i - 1]; } this.ListUploaderPeers[n + 1] = peer; } else { this.ListUploaderPeers.Add(peer); } }
/// <summary> /// Adds the peer to the list. /// If exist another peer with same ID he will be automatically updated ( delete and write on ). /// </summary> /// <param name="peer">Peer object to add.</param> public static void AddPeer(Objects.Peer peer) { peer.Date = DateTime.UtcNow; for (int i = 0; i < m_peersList.Count; i++) { if (m_peersList[i].IP == peer.IP) { m_peersList[i] = peer; PeersList.NewOrUpdatedOrDeletedPeer = true; return; } } m_peersList.Add(peer); PeersList.NewOrUpdatedOrDeletedPeer = true; }
/// <summary> /// Update the info about the peers of the selected download. /// </summary> private void UpdateSelectedDownloadPeers() { if (this.InvokeRequired) { this.Invoke(new MethodInvoker(() => { this.UpdateSelectedDownloadPeers(); })); } else { if (this.SelectedDownload != null) { DataGridViewRowCollection rows = this.dataGridView_SelectedDownloadPeers.Rows; if (rows.Count > this.SelectedDownload.ListPeers.Count) { rows.Clear(); } for (int i = 0; i < this.SelectedDownload.ListPeers.Count; i++) { Objects.Peer peer = this.SelectedDownload.ListPeers[i]; if (i >= rows.Count) { rows.Add( peer.IP, Utilities.Converterer.AutoConvertSizeFromByte(peer.DownloadSpeed) + "/s"); } else { rows[i].SetValues( peer.IP, Utilities.Converterer.AutoConvertSizeFromByte(peer.DownloadSpeed) + "/s"); } } } } }
/// <summary> /// Send a new FPR to the peer for download the next not-downloaded file pack of a this file part. /// </summary> /// <param name="download">The download object.</param> /// <param name="Peer">The IP address of peer to send the FPR message.</param> /// <returns>Return true if the message has been sended.</returns> private static bool DownloadFirstNotDownloadedFilePack(Objects.Download download, Objects.Peer Peer) { for (int i = 0; i < download.ListFileParts.Length; i++) { if (download.ListFileParts[i] > 0) { int a = i * 128; for (int n = 0; n < 128; n++) { if (download.ListFilePacks[a + n] == false) { // start to download the file part string[] Params = new string[3]; Params[0] = download.Name; Params[1] = download.SHA1; Params[2] = ((a + n) * 16384).ToString(); Messages.IMessage FprMess = Messages.MessagesFactory.Instance.CreateMessage(Messages.Commands.FPR, Params); Peer.Send(FprMess); return(true); } } } } return(false); }
/// <summary> /// Send a new FPR to the peer for download the next not-downloaded file pack of a this file part. /// </summary> /// <param name="filePackNum">The number of the file pack.</param> /// <param name="filePartNum">The number of the file part.</param> /// <param name="download">The download object.</param> /// <param name="Peer">The IP address of peer to send the FPR message.</param> /// <returns>Return true if the message has been sended; return false if the file part is completed.</returns> private static bool DownloadNextFilePackOfAFilePart(int filePackNum, int filePartNum, Objects.Download download, Objects.Peer Peer) { int nPack = filePackNum; int partEnd = (filePartNum * 128) + 128; for (int i = 0; i < 128; i++) { if (nPack < download.ListFilePacks.Length) { if (download.ListFilePacks[nPack] == false) { // download this file pack string[] Params = new string[3]; Params[0] = download.Name; Params[1] = download.SHA1; Params[2] = (nPack * 16384).ToString(); Messages.IMessage FprMess = Messages.MessagesFactory.Instance.CreateMessage(Messages.Commands.FPR, Params); Peer.Send(FprMess); return(true); } } else { return(false); } if (nPack < partEnd) { nPack++; } else { nPack = filePartNum * 128; } } return(false); }
/// <summary> /// Build a new XML_List with all the peers are contained in the Lists.PeersList. /// </summary> public static void Build_XML_List() { XmlDocument list = new XmlDocument(); list.LoadXml("<Peers></Peers>"); for (int i = 0; i < Lists.PeersList.Count; i++) { Objects.Peer peer = (Objects.Peer)Lists.PeersList.List[i]; if (peer.ID != "" && peer.ID != null) { XmlElement XE_peer = list.CreateElement("_" + peer.ID); XmlElement peer_IP = list.CreateElement("IP"); peer_IP.InnerText = peer.IP; XE_peer.AppendChild(peer_IP); XmlElement peer_time = list.CreateElement("Time"); peer_time.InnerText = peer.Date.ToString(); XE_peer.AppendChild(peer_time); XmlElement peer_files = list.CreateElement("Files"); try { for (int j = 0; j < peer.Files.Count; j++) { Objects.Peer.File file = peer.Files[j]; XmlElement file_sha = list.CreateElement("_" + file.SHA1); XmlElement file_name = list.CreateElement("Name"); file_name.InnerText = file.Name; file_sha.AppendChild(file_name); XmlElement file_size = list.CreateElement("Size"); file_size.InnerText = file.Size.ToString(); file_sha.AppendChild(file_size); peer_files.AppendChild(file_sha); } } catch { } XE_peer.AppendChild(peer_files); list.DocumentElement.AppendChild(XE_peer); } } // save the list XmlTextWriter writer = new XmlTextWriter(Global.iKiwiPath + "List.xml", null); writer.Formatting = Formatting.Indented; while (true) { try { list.Save(writer); writer.Flush(); writer.Close(); return; } catch { Thread.Sleep(1); } } }
/// <summary> /// Logs a downloaded file pack and send a new FPR message if is necessary. /// </summary> /// <param name="Download">The download object.</param> /// <param name="StartPoint">The star point of the file pack.</param> /// <param name="SenderPeer">The sender peer object.</param> /// <param name="Status">If the file-pack has been written or not ( other ).</param> public static void LogFilePack(Objects.Download Download, int StartPoint, Objects.Peer SenderPeer, Status_FilePack Status) { // indicate the downloading of a file pack SenderPeer.FilePackDownloaded = true; if (Status == Status_FilePack.Written) { #region ... int filePackNum = StartPoint / 16384; int filePartNum = StartPoint / 2097152; // control if the file pack is already been downloaded if (Download.ListFilePacks[filePackNum] == false) { // update the list of file packs Download.ListFilePacks[filePackNum] = true; // update the number of remaining file packs Download.RemainingFilePacks--; // update the list of file parts Download.ListFileParts[filePartNum]--; // control if the file part is completed if (Download.ListFileParts[filePartNum] == 0) { // update the number of remaining file parts Download.RemainingFileParts--; // control if the download is finished if (Download.RemainingFilePacks == 0) { // move the completed download from temp-directory to shared-directory File.Move(Global.TempDirectory + Download.Name, Global.SharedDirectory + Download.Name); // update download's informations Download.Progress = 100; Download.Active = false; } else { // send a new FPR to the peer for the next not downloaded file pack of a new file part StartDownloadNextFilePart(Download, SenderPeer); } } else { // send a new FPR to the peer for the next not downloaded file pack of a this file part if (DownloadNextFilePackOfAFilePart(filePackNum, filePartNum, Download, SenderPeer) == false) { StartDownloadNextFilePart(Download, SenderPeer); } } // log the file pack Download.LogFilePack(SenderPeer.IP, filePackNum); NewOrUpdatedDownload = true; } #endregion } // if the FilePack is damaged, will send a new FPR-mess to the peer; else if (Status == Status_FilePack.Damaged) { #region ... string[] Params = new string[3]; Params[0] = Download.Name; Params[1] = Download.SHA1; Params[2] = StartPoint.ToString(); Messages.IMessage FprMess = Messages.MessagesFactory.Instance.CreateMessage(Messages.Commands.FPR, Params); SenderPeer.Send(FprMess); #endregion } }
/// <summary> /// Update the existing old with the new peer ( delete and write on ). /// If the peer doesn't exist in the list he will be created. /// </summary> /// <param name="peer">Peer object to update</param> public static void UpdatePeer(Objects.Peer peer) { AddPeer(peer); }
/// <summary> /// Manage the request connection; /// it decide if create a new connection or not. /// </summary> private static void DoAcceptTcpClient(IAsyncResult ar) { try { // start a new asynchronous listening m_clientAccepted.Set(); // get the TcpClient and the NetworkStream TcpClient Client = ((TcpListener)ar.AsyncState).EndAcceptTcpClient(ar); NetworkStream Stream = Client.GetStream(); Thread.Sleep(10); // get the request message in UTF16 form int i = 0; int num_bytes_read = 0; byte[] Bytes = new byte[3072]; byte[] Req_message_byte = new byte[3072]; do { if (Stream.DataAvailable) { i = Stream.Read(Bytes, 0, Bytes.Length); Array.Copy(Bytes, 0, Req_message_byte, num_bytes_read, i); num_bytes_read += i; } else { Thread.Sleep(10); if (!Stream.DataAvailable) { break; } i = 1; } } while (i != 0); string Req_message = System.Text.Encoding.Unicode.GetString(Req_message_byte); // control if the message is correct or not string[] sub_Req_message = Req_message.Split('\n'); try { if (sub_Req_message[0].Substring(0, 4) == "Nova" && sub_Req_message[1].Substring(0, 7) == "CONNECT") { string Client_IP = sub_Req_message[2].Substring("Local-IP: ".Length).Trim(); bool connectionAccepted = false; // process the request if (Lists.PeersList.Count < Global.MaxNumberInputConnections) { connectionAccepted = true; } else { // control if there are peers that are not uploading or downloading to or from this client for (int n = 0; n < Lists.PeersList.List.Count; n++) { try { if (Lists.PeersList.List[n].DownloadInProgress == false && Lists.PeersList.List[n].UploadInProgress == false) { // remove this peer from the peers list Lists.PeersList.RemoveAndClosePeerAt(n); // accept the input connection connectionAccepted = true; break; } } catch { } } } if (connectionAccepted == true) { Utilities.Log.Write("Connection request from " + Client_IP + " accepted", Utilities.Log.LogCategory.ConnectionRequests); // create a new Objects.Peer object Objects.Peer peer = new Objects.Peer(Client_IP, Client, Stream); peer.ID = "EMPTY"; // the reply string Reply_message = Global.P2P_Protocol + "\n" + "CONNECT_OK" + "\n" + "Local-IP: " + Global.MyRemoteIP + ":" + Global.ListeningPort + "\n" + "Remote-IP: " + Client_IP + "\n" + "User-Agent: " + Global.UserAgent; // send the reply MessageSender.Send(Reply_message, Client, true); // add the peer in the Lists.PeersList() Lists.PeersList.AddPeer(peer); } else { Utilities.Log.Write("Connection request from " + Client_IP + " refused", Utilities.Log.LogCategory.ConnectionRequests); string Reply_message = Global.P2P_Protocol + "\n" + "CONNECT_NO" + "\n" + "Local-IP: " + Global.MyRemoteIP + ":" + Global.ListeningPort + "\n" + "Remote-IP: " + Client_IP + "\n" + "User-Agent: " + Global.UserAgent; byte[] buffer = System.Text.Encoding.Unicode.GetBytes(Reply_message); Stream.Write(buffer, 0, buffer.Length); Stream.Close(); Client.Close(); } } else { Utilities.Log.Write("Connection request isn't valid", Utilities.Log.LogCategory.ConnectionRequests); Stream.Close(); Client.Close(); } } catch(Exception) { Utilities.Log.Write("Connection request isn't valid", Utilities.Log.LogCategory.ConnectionRequests); Stream.Close(); Client.Close(); } } catch (Exception ex) { Utilities.Log.Write("Error to process a connection request: " + ex.Message, Utilities.Log.LogCategory.ConnectionRequests); } }
/// <summary> /// Process a file pack. /// </summary> /// <param name="FileName">The name of the file.</param> /// <param name="FileID">The ID of the file.</param> /// <param name="StartPoint">The star point of the file pack.</param> /// <param name="PackID">The ID of the binary data.</param> /// <param name="Binary">The binary data.</param> /// <param name="SenderPeer">The sender peer object.</param> public static void ProcessFilePack(string FileName, string FileID, int StartPoint, string PackID, byte[] Binary, Objects.Peer SenderPeer) { Objects.Download download = Downloader.SearchDownload(FileName, FileID); // control if exist this download and if it is actived if (download != null && download.Active == true) { // control that the binaryPack isn't damaged SHA1 sha1 = new SHA1CryptoServiceProvider(); if (PackID == BitConverter.ToString(sha1.ComputeHash(Binary)).Replace("-", "")) { #region Write to the file while (true) { try { // open ( or create ) the file ( in temp-directory ) FileStream fs = new FileStream((Global.TempDirectory + @"\" + FileName), FileMode.OpenOrCreate); // lock the access to file fs.Lock(StartPoint, 16384); // set the start-point fs.Seek(StartPoint, SeekOrigin.Begin); int count = 16384; if ((download.Size - StartPoint) < 16384) { count = ((int)download.Size - StartPoint); } // write the filePack in the file ( temp ) fs.Write(Binary, 0, count); // unlock the access to file fs.Unlock(StartPoint, 16384); fs.Close(); // log the file pack Downloader.LogFilePack(download, StartPoint, SenderPeer, Downloader.Status_FilePack.Written); break; } catch (IOException) // the file is already locked { Thread.Sleep(1); } catch (Exception ex) // other problem { Utilities.Log.Write("Downloader.cs: error to write in a file: \n" + ex.Message, Utilities.Log.LogCategory.Error); break; } } #endregion } else { // log // communicate to Downloader that the FilePack is damaged Downloader.LogFilePack(download, StartPoint, SenderPeer, Downloader.Status_FilePack.Damaged); } } }
/// <summary> /// Generic message. /// </summary> /// <param name="CommandName">The command name.</param> /// <param name="TTL">The time to live.</param> /// <param name="Encrypted">Indicates if the message is encrypted or not.</param> /// <param name="SenderPeer">The sender peer.</param> public AbstractMessage(Commands CommandName, int TTL, bool Encrypted, Objects.Peer SenderPeer = null) : this(CommandName, string.Empty, TTL, Encrypted, SenderPeer) { }
/// <summary> /// Manage the request connection; /// it decide if create a new connection or not. /// </summary> private static void DoAcceptTcpClient(IAsyncResult ar) { try { // start a new asynchronous listening m_clientAccepted.Set(); // get the TcpClient and the NetworkStream TcpClient Client = ((TcpListener)ar.AsyncState).EndAcceptTcpClient(ar); NetworkStream Stream = Client.GetStream(); Thread.Sleep(10); // get the request message in UTF16 form int i = 0; int num_bytes_read = 0; byte[] Bytes = new byte[3072]; byte[] Req_message_byte = new byte[3072]; do { if (Stream.DataAvailable) { i = Stream.Read(Bytes, 0, Bytes.Length); Array.Copy(Bytes, 0, Req_message_byte, num_bytes_read, i); num_bytes_read += i; } else { Thread.Sleep(10); if (!Stream.DataAvailable) { break; } i = 1; } } while (i != 0); string Req_message = System.Text.Encoding.Unicode.GetString(Req_message_byte); // control if the message is correct or not string[] sub_Req_message = Req_message.Split('\n'); try { if (sub_Req_message[0].Substring(0, 4) == "Nova" && sub_Req_message[1].Substring(0, 7) == "CONNECT") { string Client_IP = sub_Req_message[2].Substring("Local-IP: ".Length).Trim(); bool connectionAccepted = false; // process the request if (Lists.PeersList.Count < Global.MaxNumberInputConnections) { connectionAccepted = true; } else { // control if there are peers that are not uploading or downloading to or from this client for (int n = 0; n < Lists.PeersList.List.Count; n++) { try { if (Lists.PeersList.List[n].DownloadInProgress == false && Lists.PeersList.List[n].UploadInProgress == false) { // remove this peer from the peers list Lists.PeersList.RemoveAndClosePeerAt(n); // accept the input connection connectionAccepted = true; break; } } catch { } } } if (connectionAccepted == true) { Utilities.Log.Write("Connection request from " + Client_IP + " accepted", Utilities.Log.LogCategory.ConnectionRequests); // create a new Objects.Peer object Objects.Peer peer = new Objects.Peer(Client_IP, Client, Stream); peer.ID = "EMPTY"; // the reply string Reply_message = Global.P2P_Protocol + "\n" + "CONNECT_OK" + "\n" + "Local-IP: " + Global.MyRemoteIP + ":" + Global.ListeningPort + "\n" + "Remote-IP: " + Client_IP + "\n" + "User-Agent: " + Global.UserAgent; // send the reply MessageSender.Send(Reply_message, Client, true); // add the peer in the Lists.PeersList() Lists.PeersList.AddPeer(peer); } else { Utilities.Log.Write("Connection request from " + Client_IP + " refused", Utilities.Log.LogCategory.ConnectionRequests); string Reply_message = Global.P2P_Protocol + "\n" + "CONNECT_NO" + "\n" + "Local-IP: " + Global.MyRemoteIP + ":" + Global.ListeningPort + "\n" + "Remote-IP: " + Client_IP + "\n" + "User-Agent: " + Global.UserAgent; byte[] buffer = System.Text.Encoding.Unicode.GetBytes(Reply_message); Stream.Write(buffer, 0, buffer.Length); Stream.Close(); Client.Close(); } } else { Utilities.Log.Write("Connection request isn't valid", Utilities.Log.LogCategory.ConnectionRequests); Stream.Close(); Client.Close(); } } catch (Exception) { Utilities.Log.Write("Connection request isn't valid", Utilities.Log.LogCategory.ConnectionRequests); Stream.Close(); Client.Close(); } } catch (Exception ex) { Utilities.Log.Write("Error to process a connection request: " + ex.Message, Utilities.Log.LogCategory.ConnectionRequests); } }
/// <summary> /// Creates a message object from the input data. /// </summary> /// <param name="Message">The received message.</param> /// <param name="SenderPeer">IP:Port of the sender.</param> /// <returns>Returns the message objetc.</returns> public Messages.IMessage ParseMessage(byte[] Message, Objects.Peer SenderPeer) { // message parts Messages.Commands messageCommand; string messageID = string.Empty; int messageTTL = 0; bool messageEncryption = false; int messageParametersLength = 0; byte[] messageParameters; // split byte array int start = 0; int count = 0; byte[] buffer = null; while (true) { try { // get the command if (Message[start + 4] == RETURN_CHAR_UTF16[0] && Message[start + 5] == RETURN_CHAR_UTF16[1]) { count = 4; } else if (Message[start + 6] == RETURN_CHAR_UTF16[0] && Message[start + 7] == RETURN_CHAR_UTF16[1]) { count = 6; } else { // the message is invalid Utilities.Log.Write("Invalid input message from " + SenderPeer.IP, Utilities.Log.LogCategory.InputMessages); return(null); } buffer = new byte[count]; Buffer.BlockCopy(Message, start, buffer, 0, count); if (Enum.TryParse <Messages.Commands>(ASCIIEncoding.Unicode.GetString(buffer), out messageCommand)) { // get the other message parts bool b = false; for (int a = 0; a <= 3; a++) { start += count + 2; b = false; for (int i = start; i <= Message.Length - 1; i += 2) { if (Message[i] == RETURN_CHAR_UTF16[0] && Message[i + 1] == RETURN_CHAR_UTF16[1]) { count = i - start; b = true; break; } } if (b == true) { buffer = new Byte[count]; Buffer.BlockCopy(Message, start, buffer, 0, count); switch (a) { case 0: { messageID = ASCIIEncoding.Unicode.GetString(buffer); break; } case 1: { messageTTL = int.Parse(ASCIIEncoding.Unicode.GetString(buffer)); break; } case 2: { if (ASCIIEncoding.Unicode.GetString(buffer) == "0") { messageEncryption = false; } else { messageEncryption = true; } break; } case 3: { messageParametersLength = int.Parse(ASCIIEncoding.Unicode.GetString(buffer)); break; } } } else { // return the incompleted message break; } } // get the parameters of the message start += count + 2; count = messageParametersLength; // control if the message is complete if (count <= Message.Length - start) { messageParameters = new byte[count]; Buffer.BlockCopy(Message, start, messageParameters, 0, count); // process the single message #region get parameters and create the message object // control if the message is encrypted if (messageEncryption == true) { // decrypt the message if (messageCommand == Commands.EK) { messageParameters = Utilities.Cryptography.RsaDecryptByteToByte(messageParameters, SenderPeer.MyAsymmetricEncryptionKey); } else { messageParameters = Utilities.Cryptography.AesDecryptByteToByte(messageParameters, SenderPeer.SymmetricEncryptionKey); } } string[] strParameters; IMessage message; if (messageCommand == Commands.FP || messageCommand == Commands.XL) { byte[] binaryPart; if (messageCommand == Commands.FP) { strParameters = new string[4]; // split the byte array int parStart = -2; int parCount = 0; byte[] parBuffer = null; bool _b = false; for (int a = 0; a <= 3; a++) { parStart = parStart + parCount + 2; _b = false; for (int i = parStart; i <= messageParameters.Length - parStart; i += 2) { if (messageParameters[i] == RETURN_CHAR_UTF16[0] && messageParameters[i + 1] == RETURN_CHAR_UTF16[1]) { parCount = i - parStart; _b = true; break; } } if (_b == true) { parBuffer = new Byte[parCount]; Buffer.BlockCopy(messageParameters, parStart, parBuffer, 0, parCount); strParameters[a] = ASCIIEncoding.Unicode.GetString(parBuffer); } } parStart = parStart + parCount + 8; //parCount = Parameters.Length - start; binaryPart = new byte[16384]; Buffer.BlockCopy(messageParameters, parStart, binaryPart, 0, binaryPart.Length); } else { strParameters = new string[0]; binaryPart = new Byte[messageParameters.Length - 6]; Buffer.BlockCopy(messageParameters, 6, binaryPart, 0, binaryPart.Length); } message = CreateMessage(messageCommand, messageID, messageTTL, messageEncryption, strParameters, binaryPart); } else { strParameters = ASCIIEncoding.Unicode.GetString(messageParameters).Split('\n'); strParameters[strParameters.Length - 1] = strParameters[strParameters.Length - 1].TrimEnd('\0'); message = MessagesFactory.Instance.CreateMessage(messageCommand, messageID, messageTTL, messageEncryption, strParameters); } message.SenderPeer = SenderPeer; return(message); #endregion // check if there are other messages to be processed } else { // return the incompleted message return(null); } } else { // the message command is invalid Utilities.Log.Write("Invalid input message from " + SenderPeer.IP, Utilities.Log.LogCategory.InputMessages); return(null); } } catch (Exception ex) { Utilities.Log.Write("Error to process a message from " + SenderPeer.IP + ": " + ex.Message, Utilities.Log.LogCategory.Error); return(null); } } }