Сырой FTP Загрузить файл с пассивного сервера C # - PullRequest
0 голосов
/ 06 апреля 2011

Мне нужно получить файл с ftp-сервера, но у меня возникли определенные проблемы. Общая идея кода заключается в том, что мне нужно войти в систему три раза, а затем я получаю список файлов с сервера. Все идет хорошо, но когда я получаю два файла, которые мне нужны, я получаю SocketException: «Установленное соединение было прервано программным обеспечением на вашем компьютере»

Для ясности, первый файл не генерирует это исключение, но и ничего не загружает. Второй провал целиком.

Код выглядит следующим образом:

static void Main(string[] args)
    {
        IPHostEntry dns = Dns.GetHostEntry("SERVER");

        IPEndPoint serverIP = new IPEndPoint(dns.AddressList[0], 21);

        Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);


        sock.Connect(serverIP);

        FTPRequest("USER firstusername\n", sock);
        FTPRequest("PASS firstpass\n", sock);
        FTPRequest("USER secondusername\n", sock);
        FTPRequest("PASS secondpass\n", sock);
        FTPRequest("USER thirdusername\n", sock);
        FTPRequest("PASS thirdpass\n", sock);
        FTPRequest("TYPE A\n", sock);
        string s = FTPRequest("PASV\n", sock);
        IPEndPoint listenIP = IPEnd(s);
        Socket sock2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        sock2.Connect(listenIP);
        FTPRequest("LIST\n", sock);


        ArrayList al = new ArrayList();


        try
        {
            byte[] buffer = new byte[25000];

            int bytes = 0;

            bytes = sock2.Receive(buffer);

            Thread.Sleep(1000);

            string stringList = Encoding.ASCII.GetString(buffer, 0, bytes);



            foreach (string st in stringList.Split(' ', '\n'))
            {
                if (st.Contains(".CSV"))
                    al.Add(st.Trim());
            }
        }
        catch (Exception)
        {
            return;
        }

        sock2.Disconnect(false);

        DateTime dt = new DateTime();

        foreach (string st in al)
        {
            DateTime temp = DateTime.ParseExact(st.Split('_', '.')[4], "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
            if (temp > dt)
                dt = temp;
        }

        string file1 = "";
        string file2 = "";

        foreach (string st in al)
        {
            if (st.Contains(dt.ToString("yyyyMMdd")))
            {
                if (st.Contains("CAN"))
                    file1 = st;
                else
                    file2 = st;
            }
        }

        FTPRequest("TYPE I\n", sock);

        foreach (string file in new string[] { file1, file2 })
        {
            if (file != "")
            {
                Socket sock3 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                FTPRequest("TYPE I\n", sock);
                sock3.Connect(IPEnd(FTPRequest("PASV\n", sock)));

                FTPRequest("RETR" + file + '\n', sock);

                try
                {
                    byte[] buffer = new byte[25000];

                    int bytes = 0;

                    bytes = sock3.Receive(buffer);


                    FileStream writeStream = new FileStream(@"MYPATH" + file1, FileMode.Create);

                    while (bytes > 0)
                    {
                        writeStream.Write(buffer, 0, bytes);
                        bytes = sock3.Receive(buffer, 0);
                    }


                }
                catch (Exception)
                {
                    return;
                }
                finally
                {
                    sock3.Disconnect(false);
                }
            }
        }

        sock.Disconnect(false);
        Console.Read();

    }


    static string FTPRequest(string command, Socket sock)
    {
        string resp = string.Empty;
        Byte[] bytesReceived = new Byte[1024];
        int bytes = 0;

        Byte[] bytesSent = Encoding.ASCII.GetBytes(command);
        sock.Send(bytesSent, bytesSent.Length, 0);

        Thread.Sleep(1000);

        try
        {
            bytes = sock.Receive(bytesReceived, bytesReceived.Length, 0);
        }
        catch (Exception)
        {
        }
        return Encoding.ASCII.GetString(bytesReceived, 0, bytes);
    }

    static IPEndPoint IPEnd(string pasvResponse)
    {
        string s = pasvResponse.Split(' ')[4];
        s = s.Trim();
        s = s.Trim('(', ')');
        string[] sp = s.Split(',');
        IPHostEntry dns = new IPHostEntry();
        try
        {
            dns = Dns.Resolve(string.Format("{0}.{1}.{2}.{3}", sp[0], sp[1], sp[2], sp[3]));
        }
        catch (Exception)
        {
        }
        int port = int.Parse(sp[4]) * 256 + int.Parse(sp[5]);
        return new IPEndPoint(dns.AddressList[0], port);
    }

Я немного новичок в использовании c # для FTP, поэтому любая помощь очень ценится.

1 Ответ

3 голосов
/ 06 апреля 2011

Я бы порекомендовал просто использовать FtpWebRequest напрямую для получения информации с FTP-сервера.Вероятность возникновения ошибок гораздо ниже, поскольку это очень надежная часть базовой структуры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...