从被动服务器 C# 的原始 FTP 下载文件

发布于 2024-10-31 08:48:27 字数 4616 浏览 4 评论 0原文

我必须从 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 有点陌生,因此非常感谢任何帮助。

I have to get a file from the ftp server, but I'm having some specific trouble. The general idea of the code is that I have to log in three times, and then I get a list of the files from the server. The comes through fine, but when I go for the two files I need I get a SocketException: "An established connection was aborted by the software in your host machine"

To be clear, the first file doesn't generate this exception, but it doesn't download anything, either. The second one fails entirely.

Code is as follows:

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);
    }

I'm a bit new to using c# for FTP anything, so any help is very much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心清如水 2024-11-07 08:48:28

我建议直接使用 FtpWebRequest 来获取信息FTP 服务器。它引起错误的可能性要小得多,因为它是核心框架中非常强大的部分。

I would recommend just using FtpWebRequest directly to fetch information from an FTP server. It is far less likely to cause errors, as it's a very robust part of the core framework.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文