csaki

class FtpService

Aug 4th, 2014
333
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.62 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Net.Sockets;
  8. using System.Threading;
  9.  
  10. // THE EXCEPTION HAPPENS AT UPLOADFILE METHOD (I call it from outside)
  11.  
  12. namespace FtpProtocol_test
  13. {
  14.     class FtpService
  15.     {
  16.         // Fields //
  17.         private readonly TcpClient client = new TcpClient();
  18.         private readonly IPEndPoint _ipEndPoint;
  19.         private NetworkStream stream;
  20.  
  21.  
  22.         // Properties //
  23.         public int Port { get { return _ipEndPoint.Port; } }
  24.         public IPAddress IpAddress { get { return _ipEndPoint.Address; } }
  25.  
  26.  
  27.         // Constructors //
  28.         public FtpService(IPEndPoint ipEndpont, bool connectNow)
  29.         {
  30.             _ipEndPoint = ipEndpont;
  31.             if (connectNow)
  32.                 Connect();
  33.         }
  34.  
  35.         public FtpService(string ip, int port, bool connectNow)
  36.             : this(new IPEndPoint(IPAddress.Parse(ip), port), connectNow)
  37.         { }
  38.         public FtpService(bool connectNow)
  39.             : this(new IPEndPoint(IPAddress.Loopback, 21), connectNow)
  40.         { }
  41.  
  42.  
  43.         // Methods //
  44.  
  45.         /// <summary>
  46.         /// Method to connect to the FTP server.
  47.         /// </summary>
  48.         /// <returns>Returns a boolean value whether the connection succeeded.</returns>
  49.         public bool Connect()
  50.         {
  51.             try
  52.             {
  53.                 client.Connect(_ipEndPoint);
  54.                 stream = client.GetStream();
  55.             }
  56.             catch (Exception ex)
  57.             {
  58.                 Trace.WriteLine(ex.Message);
  59.                 return false;
  60.             }
  61.             return true;
  62.         }
  63.  
  64.         private void Send(byte[] buffer, bool doFlush = false)
  65.         {
  66.             stream.Write(buffer, 0, buffer.Length);
  67.             if (doFlush) stream.Flush();
  68.         }
  69.  
  70.         private void Read(byte[] buffer)
  71.         {
  72.  
  73.             while (!stream.DataAvailable) { Thread.Sleep(1); }
  74.             stream.Read(buffer, 0, buffer.Length);
  75.         }
  76.  
  77.         /// <summary>
  78.         /// Synchoronous method to download a file from an FTP server.
  79.         /// </summary>
  80.         /// <param name="filenamewithExtension">Name of the file with the extension located on the FTP server.</param>
  81.         /// <returns>Returns the file in binary format.</returns>
  82.         public byte[] DownloadFile(string filenamewithExtension)
  83.         {
  84.             // Verify filename, whether it exists or not
  85.             var bytes = filenamewithExtension.GetBytes();
  86.             Send(Values.FilenameDownload);
  87.             Send(bytes);
  88.             Send(Values.Endvalue, true);
  89.  
  90.             // Check results
  91.             bytes = new byte[2];
  92.             Read(bytes);
  93.             if (bytes.MembersEquals(Values.Missing))
  94.             {
  95.                 Trace.WriteLine("There is no such file found on the server!");
  96.                 return null;
  97.             }
  98.  
  99.             // Start downloading
  100.             List<byte> list = new List<byte>();
  101.             bool succeeded = false;
  102.             bytes = new byte[1024];
  103.             while (true)
  104.             {
  105.                 Send(Values.Download);
  106.                 Read(bytes);
  107.                 if (bytes.MembersEquals(Values.Success, 2))
  108.                 {
  109.                     succeeded = true;
  110.                     break;
  111.                 }
  112.                 if (bytes.MembersEquals(Values.Denied, 2) || bytes.MembersEquals(Values.NoFilename, 2))
  113.                 {
  114.                     break;
  115.                 }
  116.                 list.AddRange(bytes);
  117.             }
  118.             return succeeded ? list.ToArray() : null;
  119.         }
  120.  
  121.         /// <summary>
  122.         /// Synchronous method to download a file from the FTP server.
  123.         /// </summary>
  124.         /// <param name="filepath">Path of the file on the disk.</param>
  125.         /// <returns>Returns a boolean value whether the upload has succeeded or not.</returns>
  126.         public bool UploadFile(string filepath)
  127.         {
  128.             // Set filename and size
  129.             var filecontent = Path.GetFileName(filepath).GetBytes();
  130.             Send(Values.FilenameAndSizeUpload);
  131.             Send(filecontent);
  132.             //Send("|".GetBytes());
  133.             filecontent = File.ReadAllBytes(filepath);
  134.             //Send(BitConverter.GetBytes(filecontent.Sum(b => b)));
  135.             Send(Values.Endvalue, true);
  136.  
  137.             // Check results
  138.             var temp = new byte[2];
  139.             Read(temp);
  140.             if (temp.MembersEquals(Values.Exist))
  141.             {
  142.                 Trace.WriteLine("This file already exists on the server!");
  143.                 return false;
  144.             }
  145.  
  146.             // Start uploading
  147.             int chunkIndex = 0;
  148.             const int chunkSize = 1;
  149.             int hash;
  150.             while (filecontent.Length > chunkSize)
  151.             {
  152.                 Send(Values.Upload);
  153.                 temp = GetSubArray(filecontent, chunkIndex, chunkSize);
  154.                 Send(temp);
  155.                 Send(Values.Endvalue, true);
  156.                 hash = temp.GetHashCode();
  157.                 temp = new byte[chunkSize];
  158.                 Read(temp);
  159.                 if (!BitConverter.GetBytes(hash).MembersEquals(temp, GetActualArrayLength(temp)))
  160.                 {
  161.                     Trace.WriteLine("Hash failed!");
  162.                     return false;
  163.                     // Szar megoldás, tudom, hogy újra kellene küldenem, és a szerveroldalon erre figyelni, külön packet, etc....
  164.                 }
  165.                 chunkIndex += chunkSize;
  166.             }
  167.             if (filecontent.Length == chunkIndex) return true;
  168.  
  169.             Send(Values.Upload);
  170.             temp = GetSubArray(filecontent, chunkIndex, filecontent.Length - chunkIndex);
  171.             Send(temp);
  172.             Send(Values.Endvalue, true);
  173.             hash = temp.GetHashCode();
  174.             temp = new byte[1024];
  175.             Read(temp);
  176.             if (!BitConverter.GetBytes(hash).MembersEquals(temp, GetActualArrayLength(temp)))
  177.             {
  178.                 Trace.WriteLine("Hash failed!");
  179.                 return false;
  180.             }
  181.             return true;
  182.         }
  183.  
  184.         private static int GetActualArrayLength(byte[] array)
  185.         {
  186.             for (int i = 0; i < array.Length; i++)
  187.             {
  188.                 if (array[i] == '\0') return i;
  189.             }
  190.             return array.Length;
  191.         }
  192.         private static byte[] GetSubArray(byte[] array, int index, int length)
  193.         {
  194.             var result = new byte[length];
  195.             Array.Copy(array, index, result, 0, length);
  196.             return result;
  197.         }
  198.     }
  199. }
Advertisement
Add Comment
Please, Sign In to add comment