无法连接到远程服务器(ftp 在开发中有效,但在生产中无效)

Posted

技术标签:

【中文标题】无法连接到远程服务器(ftp 在开发中有效,但在生产中无效)【英文标题】:Unable to connect to the remote server (ftp works in development but not in production) 【发布时间】:2020-10-10 15:18:53 【问题描述】:

我正在开发一个位于 web.com 托管的共享服务器上的 asp.net mvc Web 应用程序。它在 IIS 7 和 .NET 4.0 上运行。

当我的弹出表单加载带有目录名称的下拉列表时,我收到错误“[WebException: Unable to connect to the remote server] System.Net.FtpWebRequest.GetResponse()”在我的 ftp 站点中。我能够运行我的应用程序并连接到开发中的 ftp(使用 Visual Studio 2019)。而且我可以远程登录到 ftp(默认端口 21)。

控制器代码:

[NoCache]
[Authorize]
[HttpGet]
public ActionResult UploadFile()

    ViewData["Folders"] = GetFolders();
    return View();


private IEnumerable<SelectListItem> GetFolders()

    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
    request.Method = WebRequestMethods.Ftp.ListDirectory;
    request.UseBinary = true;
    request.KeepAlive = false;
    request.Timeout = -1;
    request.UsePassive = true;
    request.Proxy = null;
    request.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
    List<SelectListItem> folders = new List<SelectListItem>();
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    Stream responseStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(responseStream);
    string names = reader.ReadToEnd();

    reader.Close();
    response.Close();

    var folderList =
        new List<string>(names.Split(new string[]  "\r\n" , StringSplitOptions.RemoveEmptyEntries)
            .ToList());
    folders = folderList.ConvertAll(a =>
    
        return new SelectListItem()
        
            Text = a.ToString(),
            Value = a.ToString(),
            Selected = false
        ;
    );
    return folders;

这是带有原始 ftpUrl 的 ftpwebrequest 日志:

System.Net Information: 0 : [11124] Current OS installation type is 'Server'.
System.Net Information: 0 : [27548]
FtpWebRequest#25592066::.ctor(ftp://ftp.mywebsite.com/ftp/)
System.Net Information: 0 : [27548]
FtpWebRequest#25592066::GetResponse(Method=NLST.)
System.Net Error: 0 : [27548] Exception in
FtpWebRequest#25592066::GetResponse - Unable to connect to the remote server.
at System.Net.FtpWebRequest.GetResponse()

这是我将 ftpUrl 更改为 root 时的 ftpwebrequest 日志:

System.Net Information: 0 : [11124] Current OS installation type is 'Server'.
System.Net Information: 0 : [20756] 
FtpWebRequest#17494990::.ctor(ftp://ftp.mywebsite.com/)
System.Net Information: 0 : [20756] 
FtpWebRequest#17494990::GetResponse(Method=NLST.)
System.Net Error: 0 : [20756] Exception in 
FtpWebRequest#17494990::GetResponse - Unable to connect to the remote server.
at System.Net.FtpWebRequest.GetResponse()

这是我将 ftpUrl 更改为 IP 地址时的 ftpwebrequest 日志:

System.Net Information: 0 : [50288] Current OS installation type is 'Server'.
System.Net Information: 0 : [25964]
FtpWebRequest#40369685::.ctor(ftp://111.222.333.44/)
System.Net Information: 0 : [25964]
FtpWebRequest#40369685::GetResponse(Method=NLST.)
System.Net Error: 0 : [25964] Exception in
FtpWebRequest#40369685::GetResponse - Unable to connect to the remote server.
at System.Net.FtpWebRequest.GetResponse()

我是 C# 和 asp.net mvc 的新手,所以请多多包涵。任何帮助将不胜感激!

【问题讨论】:

当您的应用部署在生产环境中时,您是否从服务器运行 telnet?如果您能够从您的开发环境进行连接,这并不意味着您可以从生产环境中进行连接。 感谢您的回复!当我在客户端计算机上键入“telnet ftp.mywebsite.com 21”时,我得到“220 Microsoft FTP Service”。 我可以登录到“ftp ftp.mywebsite.com”并通过在命令行中输入“ftp> ls”来列出目录。我还可以使用网络浏览器连接和查看目录。 FileZilla 也可以。我将尝试在我的代码中处理日志文件,并让你知道我得到了什么。 您是否检查过您的代码在变量 ftpUrl 中获得了预期的主机名 (ftp.mywebsite.com)?替代尝试使用 IP 地址。 @MartinPrikryl 这是日志:System.Net 信息:0:[30212] 当前操作系统安装类型为“服务器”。 System.Net 信息:0:[4960] FtpWebRequest#27524287::.ctor(ftp.mywebsite.com/ftp) System.Net 信息:0:[4960] FtpWebRequest#27524287::GetResponse(Method=NLST.) System.Net 信息:0 :[4960] RAS 支持:True System.Net 错误:0:[4960] FtpWebRequest#27524287::GetResponse 中的异常 - 无法连接到远程服务器。在 System.Net.FtpWebRequest.GetResponse() 【参考方案1】:

FTP 端口可能会针对从您的服务器打开的连接进行过滤。

一种选择可能是在该服务器上打开一个终端(不是从您的计算机或您的开发环境中)并尝试运行 telnet 到 ftp 端点。

无论如何,如果您无法尝试,并且为了确保您使用的是正确的 FTP 端点,您可以将您当前的 GetFolders 代码替换为将测试连接性的以下代码:

using System.IO;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;

private IEnumerable<SelectListItem> GetFolders()

    try
    
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
        request.Method = WebRequestMethods.Ftp.ListDirectory;
        request.UseBinary = true;
        request.KeepAlive = false;
        request.Timeout = -1;
        request.UsePassive = true;
        request.Proxy = null;
        request.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
        List<SelectListItem> folders = new List<SelectListItem>();
        FtpWebResponse response = (FtpWebResponse)request.GetResponse();
        Stream responseStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(responseStream);
        string names = reader.ReadToEnd();

        reader.Close();
        response.Close();

        var folderList =
            new List<string>(names.Split(new string[]  "\r\n" , StringSplitOptions.RemoveEmptyEntries)
                .ToList());
        folders = folderList.ConvertAll(a =>
        
            return new SelectListItem()
            
                Text = a.ToString(),
                Value = a.ToString(),
                Selected = false
            ;
        );
        return folders;
    
    catch (Exception ex)
    
        var hostname = (new Uri(ftpUrl)).Host;
        bool pingable = false;
        using (Ping pinger = new Ping())
        
            try
            
                PingReply reply = pinger.Send(hostname);
                pingable = reply.Status == IPStatus.Success;
            
            catch (Exception pEx)
            
                throw new Exception($"Error pinging hostname: pEx.ToString()", pEx);
            
        

        if (pingable)
        
            using (TcpClient tc = new TcpClient())
            
                tc.Connect(hostname, 20);
                bool stat = tc.Connected;
                if (!stat)
                    throw new Exception($"Cannot connect to hostname on port 20", ex);

                tc.Close();
            
            using (TcpClient tc = new TcpClient())
            
                tc.Connect(hostname, 21);
                bool stat = tc.Connected;
                if (!stat)
                    throw new Exception($"Cannot connect to hostname on port 21", ex);

                tc.Close();
            
            throw new Exception($"Could connect to hostname on port 20 and 21", ex);
        
        throw new Exception($"Could not ping hostname", ex);
    

新的例外应该足以让您意识到问题所在。

如果您收到类似“Could not ping ”这样的错误,那么主机名可以被解析但无法访问,您应该检查 ftp 是否在不同的网络上。 如果出现“Cannot connect to hostname on port 20”或“Cannot connect to ftpUrl on port 21”等错误,说明该端口已被过滤,请检查是否有防火墙过滤。

编辑: 我刚刚意识到在ftpUrl 中您包含了类似“ftp://host/path”的内容。这就解释了为什么你会得到“没有这样的主机是已知的”。 所以我只是编辑了代码以避免这种情况。

无论如何,从您的 cmets 来看,FTP 正在同一台服务器上运行并检查您之前发布的错误(无法连接到远程服务器),我猜可能是 FTP 站点已停止。

如果该 FTP 站点已停止,只需打开 IIS 管理器 (inetmgr),展开站点并确保 FTP 站点(它可能有任何名称,您需要检查绑定以确认它是 FTP)是运行,否则启动它。

【讨论】:

很遗憾,我无权访问共享服务器进行任何测试。在使用您提供的代码后,我收到了这个错误:“[Exception: Error pinging ftp.mywebsite.com: System.Net.NetworkInformation.PingException: An exception occurred during a Ping request.---> System.Net.Sockets .SocketException: 没有这样的主机是已知的". 虽然ftp.mywebsite.com 是公共域名,但服务器似乎不知道?改用 ip 试试。 如果尝试@FrankNielsen 的建议您仍然遇到类似的错误,请将 ftpUrl 设置为 google.com,以确认服务器是否可以访问互联网。 @FrankNielsen 我尝试将 ftpUrl 更改为 IP,但得到了相同的结果。 @MarianoDemarchi 我将其更改为 google.com 并收到此错误:System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not proper response after a period of a period时间,或建立连接失败,因为连接的主机未能响应 172.217.3.110:21【参考方案2】:

事实证明,您的 FTP 服务器实际上与您的 Web 服务器是同一台机器。所以它与 FTP 服务器相关的是localhost

一般来说,连接到本地主机服务器时应该没有任何问题。如果它不起作用,很可能是提供商明确禁止本地主机连接(尽管这很奇怪)。你确定web服务器和FTP服务器是一样的吗?


无论如何,使用 FTP 连接到本地计算机是没有意义的。如果您直接在机器上,则可以直接访问文件——这些是本地文件。使用System.IO 类,例如FileDirectory(特别是Directory.GetFiles 或类似的),而不是FtpWebRequest

【讨论】:

以上是关于无法连接到远程服务器(ftp 在开发中有效,但在生产中无效)的主要内容,如果未能解决你的问题,请参考以下文章

FTP总是无法连接到服务器

FTP无法连接

filezilla无法连接到服务器,求高手帮忙解决

使用 JAVA 到远程服务器的 FTP 连接

Amazon EC2 - 无法远程连接到 MariaDB

无法连接到远程 MySQL 服务器 (10061)