Esempio n. 1
0
        public static FilePiece parse_packet(byte[] packet)
        {
            if (packet.Length < header_size){ // packet is shorter than the header has to be
                return null;
            }
            Int32 data_length = System.BitConverter.ToInt32(packet, 0);
            if (data_length <= 0){ // no data
                return null;
            }
            Int64 piece_number = System.BitConverter.ToInt64(packet, 4);

            byte[] checksum = new byte[16];
            for(int i = 12; i < 28; i++){
                checksum[i-12] = packet[i];
            }

            byte[] data = new byte[data_length];
            for (int i = 0; i < data_length; i++){
                data[i] = packet[i+header_size];
            }

            // do a checksum
            MD5 check = new MD5CryptoServiceProvider();
            byte[] sum = check.ComputeHash(data);
            if (sum.Equals(checksum)){
                return null; // data checksum doesn't match
            }

            FilePiece piece = new FilePiece(piece_number, data);

            return piece;
        }
Esempio n. 2
0
        public static FilePiece parse_packet(byte[] packet)
        {
            if (packet.Length < 28){ // header isn't long enough
                return null;
            }
            Int32 data_length = System.BitConverter.ToInt32(packet, 0);
            if (data_length < 0){ // no data
                return null;
            }
            Int64 piece_number = System.BitConverter.ToInt64(packet, 4);
            if (piece_number < 0){ // can't have less than 0 piece number
                return null;
            }
            byte[] checksum = new byte[16];
            for(int i = 12; i < 28; i++){
                checksum[i] = packet[i];
            }
            System.ArraySegment<byte> data_segment = new System.ArraySegment<byte>(packet, 28, packet.Length-28);

            byte[] data = data_segment.Array;

            // do a checksum
            MD5 check = new MD5CryptoServiceProvider();
            byte[] sum = check.ComputeHash(data);
            if (sum.Equals(checksum)){
                return null; // data checksum doesn't match
            }

            FilePiece piece = new FilePiece(piece_number, data);

            return piece;
        }
Esempio n. 3
0
        public static byte[] get_missing_packet(Int64 missing_number)
        {
            byte[] number_data = System.BitConverter.GetBytes(missing_number);
            FilePiece piece = new FilePiece(-1, number_data);

            return piece.get_packet();
        }
        public FilePiece GetNextPiece()
        {
            if (writing){
                // polymorphism in action!
                return null;
            }

            byte[] b = GetNextChunk();
            FilePiece piece;
            if (b != null){
                piece = new FilePiece(position, b);
            }else{
                piece = null;
            }
            return piece;
        }
Esempio n. 5
0
        public void SendFileInfo()
        {
            if (file_stream == null){
                return;
            }
            byte[] b = new byte[FilePiece.data_size];
            for (int i = 0; i < b.Length ; i++){
                b[i] = 0x000000;
            }

            byte[] file_name = file_stream.GetFileName();
            file_name.CopyTo(b, 0);
            System.BitConverter.GetBytes(file_stream.GetExpectedSize()).CopyTo(b, 255);
            Encoding.UTF8.GetBytes(user_name).CopyTo(b, 255+8);

            FilePiece piece = new FilePiece(MESSAGE_FILEINFO , b);

            //			Console.WriteLine("Raw data being sent:");
            //			for (int i = 0; i < b.Length; i ++){
            //				Console.Write(b[i].ToString());
            //			}
            //			Console.WriteLine();

            network.send(piece.get_packet());
        }
Esempio n. 6
0
        public bool SendChecker()
        {
            // returns true if we're done sending
            if (file_stream == null ){
                return true;
            }

            byte[] b;
            bool received_error = false;
            b = network.PopReceiveBuffer();
            while (b != null){

                // we have data in b! Deal with it.
                FilePiece piece = FilePiece.parse_packet(b);
                if (piece != null){
                    if (piece.number > 0){
                        // do nothing. We are not a receiver!
                    }else if (piece.number == MESSAGE_RESEND){
                        // we are server! We must re-send this packet.

                        received_error = true;
                        packets_error++;
                        Int64 actual_number = BitConverter.ToInt64(piece.get_data(), 0);
                        if (actual_number != 0){
                            FilePiece specific_piece = new FilePiece(actual_number, file_stream.GetSpecificChunk(actual_number));
                            network.send(specific_piece.get_packet());
                            bytes_sent += specific_piece.get_packet_size();
                        }else{
                            Console.WriteLine("Hmm, something's wrong with that packet");
                        }
                    }
                }
                b = network.PopReceiveBuffer();
            }

            if (file_stream.GetFileStatus()){
                // done sending, just sending corrections
                if (last_error == DateTime.MinValue){
                    Console.WriteLine("last_error is null");
                    last_error = new DateTime();
                }else if (received_error){
                    last_error = DateTime.Now;
                }else if ((DateTime.Now.Subtract(last_error) ).TotalMilliseconds > CORRECTIONS_TIMEOUT){

                    Console.WriteLine("No error! Time out :)");
                    return true;
                }
            }

            // now that we're caught up, adjust the speed based on errors.
            if (received_error){
                sending_speed *= change_with_error_decrease;
            }else{
                sending_speed *= change_without_error_increase;
            }

            // returns true if all pieces have been sent.
            //Does some sending if there are things to send
            double time_spent = (DateTime.Now.AddSeconds(1) - start_time).TotalSeconds;
            while (sending_speed > (double)bytes_sent/(double)time_spent){

                FilePiece fp = file_stream.GetNextPiece();
                if (fp != null){
                    byte[] bytes = fp.get_packet();
                    if (bytes != null){
                        network.send(bytes);
                        bytes_sent += bytes.Length;
                    }else{
                        // exit loop if we're done sending file
                        return true;
                    }
                }else{
                    return true;
                }
            }
            return false;
        }
 public void WritePiece(FilePiece piece)
 {
     if (!writing){
         // polymorphism in action!
         return;
     }
     fs.Write(piece.data, 0, piece.data.Length);
     // TODO: Use BeginWrite to make it more responsive
 }
        public void WriteSpecificPiece(FilePiece piece)
        {
            // NOTE: Requires that all data pieces be EXACTLY data_size in length! (see FilePiece.cs)
            if (!writing){
                // polymorphism in action!
                return;
            }

            if (piece.number < 0){
                return;
            }

            fs.Seek(piece.number * FilePiece.data_size, SeekOrigin.Begin);
            fs.Write(piece.data, 0, piece.data.Length);
        }
Esempio n. 9
0
 public void send_file_piece(FilePiece piece)
 {
     send( piece.get_packet());
 }
Esempio n. 10
0
        public void WriteSpecificPiece(FilePiece piece)
        {
            // NOTE: Requires that all data pieces be EXACTLY data_size in length! (see FilePiece.cs)
            if (!writing){
                // polymorphism in action!
                Console.WriteLine("We're not writing. Don't call this function!");
                return;
            }

            if (piece.number < 0){
                Console.WriteLine("Don't tell us to write a non-existant piece.");
                return;
            }

            fs.Seek(piece.number * FilePiece.data_size, SeekOrigin.Begin);
            fs.Write(piece.get_data(), 0, piece.data.Length);

            if (received_pieces.Count <= 1 && received_pieces[0].Equals(piece.number - 1)){
                received_pieces.Clear();
                received_pieces.Add(piece.number);
            }else{
                if (received_pieces.Contains(piece.number)){
                    Console.WriteLine("Detected Duplicate packet");
                    received_pieces.Remove(piece.number);
                }else{
                    received_pieces.Add(piece.number);
                }
            }
        }
Esempio n. 11
0
        public bool SendChecker()
        {
            // returns true if we're done sending
            if (file_stream == null ){
                return true;
            }

            byte[] b;
            bool received_error = false;
            b = network.PopReceiveBuffer();
            while (b != null){

                // we have data in b! Deal with it.
                FilePiece piece = FilePiece.parse_packet(b);
                if (piece != null){
                    if (piece.number > 0){
                        // do nothing. We are not a receiver!
                    }else if (piece.number == MESSAGE_RESEND){
                        // we are server! We must re-send this packet.
                        received_error = true;
                        packets_error++;
                        FilePiece specific_piece = new FilePiece(piece.number, file_stream.GetSpecificChunk(piece.number));
                        network.send(specific_piece.get_packet());
                        bytes_sent += specific_piece.get_packet_size();
                    }
                }
                b = network.PopReceiveBuffer();
            }

            if (file_stream.GetFileStatus()){
                return true;
                // done sending, just sending corrections
            }

            // now that we're caught up, adjust the speed based on errors.
            if (received_error){
                sending_speed *= change_with_error_decrease;
            }else{
                sending_speed *= change_without_error_increase;
            }

            // returns true if all pieces have been sent.
            //Does some sending if there are things to send
            if (!file_stream.GetFileStatus()){
                double time_spent = (DateTime.Now.AddSeconds(1) - start_time).TotalSeconds;
                while (sending_speed > (double)bytes_sent/(double)time_spent){

                    FilePiece fp = file_stream.GetNextPiece();
                    if (fp != null){
                        byte[] bytes = fp.get_packet();
                        if (bytes != null){
                            network.send(bytes);
                            bytes_sent += bytes.Length;
                        }else{
                            // exit loop if we're done sending file
                            return true;
                        }
                    }else{
                        return true;
                    }
                }
                return false;
            }else{
                // file stream is done, so we're done sending!
                return true;
            }
        }