private DownloadPacket receive(CommunicationPacket p) { UInt64 realSerial = CommunicationFacade.ComputeRealNumber(p.SerialNumber, this.required, UInt16.MaxValue, (uint)Sizes.WINDOW_SIZE); DownloadPacket toReturn = new DownloadPacket(p.Data, p.ConnectionNumber, p.Flags, realSerial);; Logger.WriteLine($"Downloader recive packet with serial={toReturn.SerialNumber}"); return(toReturn); }
public void AcceptFile() { try { byte[] empty = new byte[] { }; IPriorityQueue <DownloadPacket, UInt64> queue = new SimplePriorityQueue <DownloadPacket, UInt64>(); //TODO add priority queue while (true) { DownloadPacket pack = this.receive(CommunicationFacade.Receive(this.socket)); pack = this.validatePacket(pack); if (pack.Flags == (byte)Flag.FIN) { Logger.WriteLine("All data arrive", ConsoleColor.Cyan); CommunicationFacade.Send(this.socket, new CommunicationPacket(this.connectionNumber, 0, Convert.ToUInt16(this.required & UInt16.MaxValue), (byte)Flag.FIN, empty)); return; } queue.Enqueue(pack, pack.SerialNumber); //Attach into priority queue while (queue.Count > 0 && queue.First.SerialNumber <= this.required) { DownloadPacket toProccess = queue.Dequeue(); if (toProccess.SerialNumber < this.required) { continue; } Logger.WriteLine($"Accepted packet {toProccess.SerialNumber}"); this.outFile.Write(toProccess.Data); this.required += (uint)toProccess.Data.Length; if (toProccess.Data.Length != 255) { Logger.WriteLine("Last packet arrive, waiting to FIN packet", ConsoleColor.Cyan); this.waitingToFin = true; } } Logger.WriteLine($"Waiting for packet {this.required}"); CommunicationFacade.Send(this.socket, new CommunicationPacket(this.connectionNumber, 0, Convert.ToUInt16(this.required & UInt16.MaxValue), 0, empty)); } } catch (CommunicationException) { Logger.WriteLine("Occurs error during communication", ConsoleColor.Yellow); throw new TerminateException(); } catch (InvalidPacketException e) { Logger.WriteLine($"Obtained invalid packet: {e.Message}", ConsoleColor.Yellow); CommunicationFacade.Send(this.socket, new CommunicationPacket(this.connectionNumber, 0, Convert.ToUInt16(this.required & UInt16.MaxValue), (byte)Flag.RST, new byte[] { })); throw new TerminateException(); } }
private DownloadPacket validatePacket(DownloadPacket p) { if (p.ConnectionNumber != this.connectionNumber) { throw new InvalidPacketException($"Connection number not match, required: {this.connectionNumber:X} accepted: {p.ConnectionNumber:X}"); } if (p.Flags > 0 && p.Flags != (byte)Flag.FIN && p.Flags != (byte)Flag.SYN && p.Flags != (byte)Flag.RST) { throw new InvalidPacketException($"Invalid packet, obtained {Convert.ToString(p.Flags, 2)}"); } if (!waitingToFin) { UInt64 i = 0; UInt64 max = (UInt64)Sizes.WINDOW_PACKETS * 4; for (i = 0; i < max; i++) { if (p.SerialNumber + i * (UInt64)Sizes.MAX_DATA == this.required || p.SerialNumber + i * (UInt64)Sizes.MAX_DATA == this.required + (UInt64)Sizes.WINDOW_SIZE) { break; } } if (i == max) { throw new InvalidPacketException($"Invalid packet serial, min required: {this.required} max required: {this.required + (uint)Sizes.WINDOW_SIZE}, obtained: {p.SerialNumber}"); } } if (p.Flags == (byte)Flag.FIN && p.Data.Length > 0) { throw new InvalidPacketException("Packet with FIN contains data"); } if (p.Flags == (byte)Flag.RST) { throw new CommunicationException(); } return(p); }
private void EnviarPeticionDescargaBGWorker(object sender, DoWorkEventArgs e) { ActualizarTextboxInfoEstadoDescarga(String.Format("Enviando petición de descarga: {0}", (String)e.Argument)); string text = (String)e.Argument; string[] palabras = text.Split(':'); string nombreArchivo = palabras[0]; string para = palabras[1]; DownloadPacket packet = new DownloadPacket(); packet.nombreArchivo = nombreArchivo; packet.nombreNodoDestino = para; packet.comando = "_PETICION_DESCARGA_"; if (EnviandoDescarga != null) { EnviandoDescarga(this, new DescargaChangedEventArgs(packet)); ActualizarTextboxInfoEstadoDescarga(String.Format("Petición de descarga enviada con éxito.", (String)e.Argument)); } }
private void EnviarBusquedaRecursoBGWorker(object sender, DoWorkEventArgs e) { ActualizarTextboxInfoEstadoDescarga(String.Format("Enviando busqueda: {0}.", (String)e.Argument)); if (EnviandoBusqueda != null) { DownloadPacket packet = new DownloadPacket(); packet.nombreArchivo = (String)e.Argument; packet.nombreNodoDestino = "*"; //busqueda enviada a todos los nodos conectados (*) packet.comando = "_BUSQUEDA_"; if (EnviandoBusqueda != null) { EnviandoBusqueda(this, new DescargaChangedEventArgs(packet)); ActualizarTextboxInfoEstadoDescarga(String.Format("Buscando...\n")); } else { ActualizarTextboxInfoEstadoDescarga("Error de envío. Por favor, inténtelo de nuevo. Si el error persiste, reinicie la aplicación."); } } }