Priznám sa, že na internete je minimum funkčných kódov na sťahovanie súborov z FTP cez PROXY, tak som sa rozhodol napísať svoj vlastný, no čo je najpodstatnejšie, overený a funkčný zdrojový kód. Napísal som funkciu Download_from_FTP, ktorá má 2 vstupné a jeden výstupný parameter. Vstupné parameter RemoteFile – meno súboru, ktorý sa má stiahnuť, Path – cesta kam sa má súbor nakopírovať na vase PC môžete samozrejme kopírovať súbor aj inam) a výstupný parameter ErrMsg, ktorý sa vyplní chybovou hláškou v prípade zlyhania sťahovania súboru. Funkcia má návratovú hodnotu typu Boolean, čiža ak uspeje je hodnota true a ka nie, false. Zadefinoval som si vlastnú triedu na výnimky ProxySocketException ktorú si uložte do ľubovoľného súboru *.cs a pripojte potom cez klauzulu using do skriptu. Ďalej sú k funkcii potrebné ešte funkcie GetFileLengthFromHeader a SearchBytes, ktoré si nakopírujte k funkcii Download_from_FTP. Konštanty na pripojenie, t.j. meno FTP a PROXY a autentikačné údaje sú farebne vyznačené vo funkcii a sú na pohľa zrejmé. Zdrojový kód som kompiloval vo verzii C# Microsoft Visual Studio Enterprise C# 2017 verzia 15.5.1, Target framework: .NET Framework 4.5.1. Dúfam, že niekomu bude kód nápomocný. S pozdravom.
Kód v c# (ProxySocketException ):
public class ProxySocketException : Exception
{
public ProxySocketException()
{
}
public ProxySocketException(string message) : base(message)
{
}
public ProxySocketException(string message, Exception innerException) : base(message, innerException)
{
}
protected ProxySocketException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
Kód v c# (Download_from_FTP ):
System.Int64 GetFileLengthFromHeader(string[] Header)
{
System.Int64 l = 0;
foreach (string item in Header)
{
if (item.Length > 15 && item.Substring(0, 15).CompareTo("Content-Length:") == 0)
{
string strLen = item.Split(" ".ToCharArray())[1];
return Convert.ToInt64(strLen);
}
}
return l;
}
int SearchBytes(byte[] haystack, byte[] needle)
{
int len = needle.Length;
int limit = haystack.Length - len;
int k;
for (int i = 0; i <= limit; i++)
{
k = 0;
for (; k < len; k++)
{
if (needle[k] != haystack[i + k]) break;
}
if (k == len) return i;
}
return -1;
}
}
Kód v c# (Hlavná funkcia: ):
bool Download_from_FTP(string RemoteFile, string Path, out string ErrMsg)
{
const int RECV_SIZE = 64 * 1024;
ErrMsg = string.Empty;
try
{
var proxyAuthB64Str = Convert.ToBase64String(Encoding.ASCII.GetBytes("PROXY_USERNAME" + ":" + "PROXY_PASSWORD"));
var sendStr = "GET http://" + "FTP_USERNAME" + ":" + "FTP_PASSWORD" + "@" + " FTP IP alebo domenove meno " + "PATH – cesta k suboru na FTP" + RemoteFile + " HTTP/1.1\n"
+ "Host: " + "FTP IP alebo domenove meno" + "\n"
+ "User-Agent: Mozilla/4.0 (compatible; Eradicator; dotNetClient)\n"
+ "Proxy-Authorization: Basic " + proxyAuthB64Str + "\n"
+ "Content-Type: application/octet-stream\n"
+ "Connection: close\n\n";
var sendBytes = Encoding.ASCII.GetBytes(sendStr);
using (var ProxySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
ProxySocket.Connect("PROXY_HOST – IP alebo domenove meno", "3128");
if (!ProxySocket.Connected) throw new ProxySocketException ();
// sending data protocol to FTP ...
ProxySocket.Send(sendBytes);
// buffer for the received data from FTP ...
byte[] Buffer = new byte[RECV_SIZE];
// read first packet, Buffr_size - size of first read packet ...
int Buffer_size = ProxySocket.Receive(Buffer, RECV_SIZE, SocketFlags.Partial);
if (Buffer_size == 0) throw new ProxySocketException("No bytes recieved from " + " FTP IP alebo domenove meno " + "PATH – cesta k suboru na FTP");
// Check result of recieved data from the header ...
var Header = new string(Encoding.ASCII.GetChars(Buffer)).Split("\r\n".ToCharArray());
var responseFirstLine = Header.Take(1).ElementAt(0);
var httpResponseDescription = Regex.Replace(responseFirstLine, @"HTTP/1\.\d (\d+) (\w+)", "$2");
// check, if received data OK ...
if (httpResponseDescription != "OK")
{
throw new ProxySocketException("Error: " + responseFirstLine);
}
// size of the buffer read from the first packet ...
byte[] FILE_SEPARATOR = new byte[] { 0x0D, 0x0A, 0x0D, 0x0A };
int File_offset = SearchBytes(Buffer, FILE_SEPARATOR);
if (File_offset == -1)
{
throw new Exception("Recieved data error - no joined file data: " + new string(Encoding.ASCII.GetChars(Buffer)));
}
File_offset += FILE_SEPARATOR.Length;
// expected size of the downloaded file ...
System.Int64 FileSizeHeader = GetFileLengthFromHeader(Header);
// Checker of the downloaded file ...
System.Int64 FileSize = 0;
StreamWriter fstream = new StreamWriter(Path + RemoteFile);
try
{
// Write first downloaded file packet placed behind the header data ...
fstream.BaseStream.Write(Buffer, File_offset, Buffer_size - File_offset);
FileSize = Buffer_size - File_offset;
// write the next packets ...
while ((Buffer_size = ProxySocket.Receive(Buffer, RECV_SIZE, SocketFlags.Partial)) > 0)
{
fstream.BaseStream.Write(Buffer, 0, Buffer_size);
FileSize += Buffer_size;
}
}
finally
{
fstream.Close();
fstream.Dispose();
fstream = null;
}
sendBytes = null;
sendStr = null;
Buffer = null;
Header = null;
if (FileSize != FileSizeHeader)
throw new ProxySocketException("Unable to download file " + RemoteFile + ". Not all bytes downloaded.");
}
return ErrMsg.Length == 0;
}
catch (Exception ex)
{
ErrMsg = ex.Message;
return false;
}
}







