简体   繁体   中英

Unable to connect to the remote server (ftp works in development but not in production)

I'm working on an asp.net mvc web application that is on a shared server hosted by web.com. It runs on IIS 7 and .NET 4.0.

I'm getting the error " [WebException: Unable to connect to the remote server] System.Net.FtpWebRequest.GetResponse() " when my popup form loads it's dropdown list with names of directories in my ftp site. I'm able to run my application and connect to the ftp in development (using visual studio 2019). And I'm able to te.net to the ftp (default port 21).

Controller code:

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

This is the ftpwebrequest log with the original ftpUrl:

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()

This is the ftpwebrequest log when I change the ftpUrl to root:

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()

This is the ftpwebrequest log when I change the ftpUrl to an IP address:

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()

I'm new to C# and asp.net mvc so please bear with me. Any help will be very much appreciated!

It's possible that FTP ports are filtered for connections opened from your server.

One option could be to open a terminal on that server (not from your computer or from your dev environment) and try to run te.net to the ftp endpoint.

Anyway if you can't try that and also to be sure you're using the proper FTP endpoint, you could replace your current code for GetFolders with the following that is going to test connectivity:

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

The new exception should be enough to make you realize of what is the issue.

  • If you get an error like "Could not ping <something>", then hostname could be resolved but it's not reachable, you should check if the ftp is on a different.network.
  • If you get an error like "Cannot connect to hostname on port 20" or "Cannot connect to ftpUrl on port 21", the port is filtered, you should check if there is any firewall filtering it.

EDIT: I just realized that in ftpUrl you're including something like "ftp://host/path". That explains why you get the "No such host is known". So I just edited the code to avoid that.

Anyway from your comments, the FTP is running on the same server and checking the error you posted before (Unable to connect to the remote server), I guess it might be that the FTP site is stopped.

If that FTP site is stopped, just open the IIS manager (.netmgr), expand sites and make sure that the FTP site (it might have any name, you'll need to check the binding to confirm it's the FTP) is running, otherwise start it.

It turned out that your FTP server is actually the same machine as your web server. So it's localhost in relation to the FTP server.

In general, there should not be any problem, when connecting to a localhost server. If it does not work, chances are that the provider explicitly forbids localhost connection (though it's strange). Are you really sure that the web server and FTP server are the same?


Anyway, it makes no sense to connect to a local machine using FTP. If you are on the machine directly, you can directly access the files – Those are local files. Use System.IO classes, like File or Directory (specifically Directory.GetFiles or similar), not FtpWebRequest .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM