2

我试图在给定的一组 ips 上找到所有接受匿名连接的 ftp 服务器。

基本上,我得到了我想要检查的 IP,然后在每个 IP 上尝试一个 ListDirectory。如果我没有例外,则 ftp 存在并且可以访问。

我正在使用异步方法来验证 IP,这使事情变得更快。但是,我需要等到所有异步调用都返回。为此,我在我拥有的异步调用数量上保留了一个计数器,问题是这个计数器永远不会变为 0。

我的代码如下所示:

迭代IP:

static int waitingOn;
public static IEnumerable<Uri> GetFtps()
{
    var result = new LinkedList<Uri>();
    waitingOn = 0;

    IPNetwork ipn = IPNetwork.Parse("192.168.72.0/21");
    IPAddressCollection ips = IPNetwork.ListIPAddress(ipn);

    foreach( var ip in ips )
    {
        VerifyFtpAsync(ip, result);
    }

    while (waitingOn > 0)
    {
        Console.WriteLine(waitingOn);
        System.Threading.Thread.Sleep(1000);
    }

    return result;
}

并验证每个 IP:

public async static void VerifyFtpAsync( IPAddress ip, LinkedList<Uri> ftps )
{
    ++waitingOn;
    try
    {
        Uri serverUri = new Uri("ftp://" + ip);
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
        request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
        request.Timeout = 10000;
        request.Credentials = new NetworkCredential("anonymous", "roim@search.com");

        FtpWebResponse response = (FtpWebResponse) await request.GetResponseAsync();

        // If we got this far, YAY!
        ftps.AddLast(serverUri);
    }
    catch (WebException)
    {
    }
    --waitingOn;
}
4

2 回答 2

1

async void首先,除非您正在编写事件处理程序,否则您不应该使用。

async接下来,如果您的方法可以并行运行(例如,如果此代码在控制台应用程序中运行),您确实需要保护变量和集合免受多线程访问。在您的情况下,听起来您可能想要使用Task.WhenAll而不是手动计数器,并删除共享集合。

public async static Task<Uri> VerifyFtpAsync(IPAddress ip)
{
  try
  {
    ...
    return serverUri;
  }
  catch (WebException)
  {
    return null;
  }
}

...

var ipTasks = ips.Select(ip => VerifyFtpAsync(ip));
var allResults = await Task.WhenAll(ipTasks);
var result = allResults.Where(url => url != null).ToArray();
于 2013-03-17T03:10:21.640 回答
1

代替

FtpWebResponse response = (FtpWebResponse) await request.GetResponseAsync(); 

带同步码

FtpWebResponse response = (FtpWebResponse) request.GetResponse();

FtpWebRequest.GetResponseAsync没有针对特定的 FTP 被覆盖,并且来自基WebRequest类,它似乎无法处理这个权利。

于 2021-09-15T13:40:58.103 回答