【问题标题】:The results of ports scanning seem to be incorrect while using AsyncCallback使用 AsyncCallback 时端口扫描的结果似乎不正确
【发布时间】:2012-01-26 13:43:03
【问题描述】:

我正在尝试对给定的 IP 地址进行端口扫描,其范围为 20 个端口。我知道端口 80 是开放的,而所有其他端口都是关闭的。我的代码显示所有端口都是打开的。

我正在尝试使用异步 TCPClient 来实现端口扫描。

这里可能有什么问题?我错过了什么吗?

private void btnStart_Click(object sender, EventArgs e)
{
    for (int port = 80; port < 100; port++)
    {
        ScanPort(port);
    }
}

private void ScanPort(int port)
{
    using (TcpClient client = new TcpClient())
    {
        client.BeginConnect(IPAddress.Parse("74.125.226.84"), port, new AsyncCallback(CallBack), client);
    }
}

private void CallBack(IAsyncResult result)
{
    using (TcpClient client = (TcpClient)result.AsyncState)
    {
        try
        {
            this.Invoke((MethodInvoker)delegate
            {
                txtDisplay.Text += "open" + Environment.NewLine;
            });
        }
        catch
        {
            this.Invoke((MethodInvoker)delegate
            {
                txtDisplay.Text += "closed" + Environment.NewLine;
            });
        }
    }
}

这就是我现在拥有的 CallBack 方法:

    private void CallBack(IAsyncResult result)
    {
        using (TcpClient client = (TcpClient)result.AsyncState)
        {
            client.EndConnect(result);

            if (client.Connected)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    txtDisplay.Text += "open" + Environment.NewLine;
                });
            }
            else
            {
                this.Invoke((MethodInvoker)delegate
                {
                    txtDisplay.Text += "closed" + Environment.NewLine;
                });
            }
        }
    }

【问题讨论】:

  • 你到底在抓什么?将文本设置为open时出错?
  • @todda.speot.is,我正在尝试检查端口是否打开。我知道不使用 asynccallback 我可以使用 client.connected 但不确定如何签入回调方法。认为这个解决方案可能有效。
  • 是的,但是代码将文本设置为打开,如果设置文本时出现异常,将尝试将文本设置为关闭。您的代码没有检查端口是打开还是关闭,它只是附加“打开”,如果以某种方式无法附加“关闭”。你需要检查result是否包含失败。
  • @todda.speot.is,啊!好点子。
  • @NewHelpNeeder 您仍然需要修改 ScanPort 方法以使其不会处理客户端,请参阅我更新的答案。

标签: c# winforms asynccallback


【解决方案1】:

声明:

using (TcpClient client = new TcpClient())
{
    client.BeginConnect(IPAddress.Parse("74.125.226.84"), port, new AsyncCallback(CallBack), client);
}

创建一个新的 TcpClient,然后调用 BeginConnect,然后在到达回调之前立即释放客户端。请记住,BeginConnect 方法不是阻塞的。客户端的处理应该只发生在回调中,所以 ScanPort 方法应该是这样的:

private void ScanPort(int port)
{
    var client = new TcpClient();
    try {
        client.BeginConnect(IPAddress.Parse("74.125.226.84"), port, new AsyncCallback(CallBack), client);
    } catch (SocketException) {
        ...
        client.Close();
    }
}

在回调中你也应该调用EndConnect:

using (TcpClient client = (TcpClient)result.AsyncState)
{
    try
    {
        client.EndConnect(result);
        this.Invoke((MethodInvoker)delegate
        {
            txtDisplay.Text += "open" + Environment.NewLine;
        });
    }
    catch
    {
        this.Invoke((MethodInvoker)delegate
        {
            txtDisplay.Text += "closed" + Environment.NewLine;
        });
    }

【讨论】:

    猜你喜欢
    • 2020-10-24
    • 2022-08-13
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多