无法连接到远程服务器ftp在开发中起作用,但在生产中不起作用

问题描述

我正在使用由web.com托管的共享服务器上的asp.net mvc Web应用程序。它可以在IIS 7和.NET 4.0上运行。

当我的弹出表单加载带有目录名称的下拉列表时,出现错误 [WebException:无法连接到远程服务器] 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的新手,所以请多多包涵。任何帮助将不胜感激!

解决方法

可能为从服务器打开的连接筛选了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);
    }
}

新的异常应该足以使您意识到问题所在。

  • 如果出现类似“无法ping ”的错误,则可以解析主机名,但无法访问主机名,应检查ftp是否在其他网络上。
  • 如果出现类似“无法在端口20上连接到hostname或”无法在端口21上连接到ftpUrl”的错误,则说明该端口已被过滤,请检查是否有防火墙对其进行过滤。

编辑: 我刚刚意识到,在ftpUrl中,您将包含“ ftp:// host / path”之类的内容。这就解释了为什么您会收到“未知此类主机”的原因。 所以我只是编辑代码来避免这种情况。

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

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

,

事实证明,您的FTP服务器实际上与Web服务器在同一台计算机上。因此,与FTP服务器有关的是localhost

通常,连接到本地主机服务器时应该没有任何问题。如果不起作用,则提供程序可能会明确禁止localhost连接(尽管很奇怪)。您真的确定Web服务器和FTP服务器相同吗?


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